Метод reduce

Метод reduce

Технический фундамент reduce

reduce последовательно переносит состояние из шага в шаг через аккумулятор acc.
Тип аккумулятора задается initialValue и может быть числом, строкой, массивом или объектом.

const nums = [1, 2, 3];
const total = nums.reduce((acc, n) => acc + n, 0);

console.log(total); // 6

Ключевой момент: reduce — это универсальный механизм свертки массива в одно итоговое значение.

Синтаксис

const result = array.reduce((acc, element, index, arr) => {
  return updatedAcc;
}, initialValue);
  • acc — накопитель;
  • element — текущий элемент;
  • initialValue — стартовое значение накопителя.

Простой пример: сумма

const prices = [100, 250, 50];

const total = prices.reduce((sum, price) => sum + price, 0);
console.log(total); // 400

Пример посложнее: группировка

const users = [
  { name: 'Ann', role: 'admin' },
  { name: 'Max', role: 'user' },
  { name: 'Leo', role: 'user' },
];

const grouped = users.reduce((acc, user) => {
  if (!acc[user.role]) {
    acc[user.role] = [];
  }
  acc[user.role].push(user.name);
  return acc;
}, {});

console.log(grouped); // { admin: ['Ann'], user: ['Max', 'Leo'] }

Почему initialValue лучше указывать явно

Без initialValue первый элемент массива станет стартовым acc, и это может ломать логику на пустом массиве.

// Ошибка на пустом массиве:
// [].reduce((a, b) => a + b)

const safeTotal = [].reduce((sum, n) => sum + n, 0);
console.log(safeTotal); // 0

Проверь себя: что случится, если убрать 0 во втором аргументе у reduce для пустого массива?

Подсказка: будет ошибка TypeError (reduce не умеет стартовать на пустом массиве без initialValue).

Смотри, что важно: если initialValue не передан, reduce начинает с элемента array[0], а callback запускает с array[1].

const nums2 = [10, 20, 30];
const total2 = nums2.reduce((acc, n) => acc + n);

// шаги будут такие:
// acc = 10 (первый элемент)
// n = 20
// n = 30

console.log(total2); // 60

Микро-сценарии

  1. Подсчет общей суммы корзины.
  2. Построение объекта вида { id: item } для быстрого доступа.
const byId = products.reduce((acc, product) => {
  acc[product.id] = product;
  return acc;
}, {});

Типичные ошибки

  • Забывать return acc внутри callback.
  • Не передавать initialValue.
  • Пытаться решить reduce слишком простую задачу, где хватает map или filter.
  • Делать callback слишком сложным и нечитаемым.

Анти-провал: сначала словами формулируй накопитель («я собираю сумму», «я собираю объект», «я собираю массив»), потом пиши код.

Краткий итог

  • reduce сворачивает массив в одно итоговое значение.
  • Главная ось метода: acc + текущее значение + return нового acc.
  • initialValue делает код безопаснее и предсказуемее.
  • reduce хорош для суммы, группировок, построения словарей.
  • Если задача простая, не усложняй: иногда лучше map или filter.