Learn JavaScript

reduce() - метод для сворачивания массива в одно значение в JavaScript

reduce() проходит по массиву и постепенно сводит его к одному итоговому значению.

Это может быть число, строка, объект, массив или вообще любое другое значение.

Синтаксис

array.reduce(callback)
array.reduce(callback, initialValue)

callback - функция, которая вызывается для каждого элемента массива.

initialValue - начальное значение аккумулятора.

Что делает reduce()

Во время работы reduce() на каждом шаге берёт текущее накопленное значение и текущий элемент массива, а потом возвращает новое накопленное значение.

const numbers = [1, 2, 3, 4];

const result = numbers.reduce((accumulator, value) => {
  return accumulator + value;
}, 0);

console.log(result); // 10

Здесь массив свёлся к одному числу.

accumulator и currentValue

Чаще всего callback выглядит так:

array.reduce((accumulator, currentValue) => {
  // ...
}, initialValue)
  • accumulator - накопленное значение с предыдущего шага
  • currentValue - текущий элемент массива

Именно поэтому reduce() часто используют для суммы, подсчётов, группировки и сборки объектов.

Что возвращает reduce()

reduce() возвращает одно итоговое значение.

const numbers = [2, 3, 4];

const result = numbers.reduce((acc, value) => acc * value, 1);

console.log(result); // 24

Результат здесь - не массив, а одно число.

Зачем нужен initialValue

initialValue задаёт стартовое значение аккумулятора.

const numbers = [1, 2, 3];

const result = numbers.reduce((acc, value) => acc + value, 0);

console.log(result); // 6

Это самый безопасный и понятный вариант использования reduce().

Что будет без initialValue

Если initialValue не передать, reduce() возьмёт первый элемент массива как начальный аккумулятор, а обход начнётся со второго элемента.

const numbers = [1, 2, 3];

const result = numbers.reduce((acc, value) => acc + value);

console.log(result); // 6

Это работает, но может путать.

Из-за этого в обычном коде initialValue часто всё-таки передают явно.

Пустой массив и ошибка

Если массив пустой и initialValue не указан, reduce() выбросит ошибку.

const numbers = [];

// numbers.reduce((acc, value) => acc + value); // TypeError

Если передать начальное значение, всё будет нормально:

const numbers = [];

const result = numbers.reduce((acc, value) => acc + value, 0);

console.log(result); // 0

Это одна из самых важных причин, почему initialValue лучше не пропускать.

Сумма элементов

Самый популярный пример с reduce() - посчитать сумму массива.

const numbers = [10, 20, 30];

const total = numbers.reduce((acc, value) => acc + value, 0);

console.log(total); // 60

Сборка объекта

reduce() часто используют, чтобы собрать объект из массива.

const pairs = [
  ["name", "Anna"],
  ["age", 25],
];

const result = pairs.reduce((acc, [key, value]) => {
  acc[key] = value;
  return acc;
}, {});

console.log(result); // { name: "Anna", age: 25 }

Группировка значений

Через reduce() можно группировать элементы по условию.

const words = ["cat", "car", "dog"];

const grouped = words.reduce((acc, word) => {
  const firstLetter = word[0];

  if (!acc[firstLetter]) {
    acc[firstLetter] = [];
  }

  acc[firstLetter].push(word);
  return acc;
}, {});

console.log(grouped);
// { c: ["cat", "car"], d: ["dog"] }

reduce() не меняет исходный массив

Сам метод reduce() не изменяет массив.

const numbers = [1, 2, 3];
const result = numbers.reduce((acc, value) => acc + value, 0);

console.log(numbers); // [1, 2, 3]
console.log(result);  // 6

Но внутри callback можно менять внешние данные или объекты, если так написать.

reduce() и map()

map() возвращает новый массив той же длины.

reduce() возвращает одно итоговое значение.

const numbers = [1, 2, 3];

console.log(numbers.map((value) => value * 2)); // [2, 4, 6]
console.log(numbers.reduce((acc, value) => acc + value, 0)); // 6

reduce() и forEach()

forEach() просто перебирает элементы и ничего не возвращает.

reduce() накапливает результат и возвращает его.

const numbers = [1, 2, 3];

const result = numbers.reduce((acc, value) => acc + value, 0);

console.log(result); // 6

Если нужен итоговый результат в конце обхода, чаще смотрят именно в сторону reduce().

Аргументы callback

Callback в reduce() может получать до четырёх аргументов:

array.reduce((accumulator, currentValue, index, array) => {
  // ...
}, initialValue)
  • accumulator - накопленное значение
  • currentValue - текущий элемент
  • index - индекс текущего элемента
  • array - сам исходный массив

Обычно в коде чаще всего используют первые два.

Пустые слоты

reduce() пропускает пустые слоты массива.

const arr = Array(3);

const result = arr.reduce((acc, value) => acc + 1, 0);

console.log(result); // 0

Callback здесь не вызывается для пустых слотов.

Когда это полезно

reduce() удобно использовать, когда:

  • нужно получить одно итоговое значение из массива
  • нужно посчитать сумму, произведение или количество
  • нужно собрать объект, массив или другую структуру данных
  • важно выразить это как последовательное накопление результата

Частые ошибки

Забывать initialValue

const numbers = [];

// numbers.reduce((acc, value) => acc + value); // TypeError

На пустом массиве без начального значения метод упадёт.

Не возвращать accumulator

const numbers = [1, 2, 3];

const result = numbers.reduce((acc, value) => {
  acc + value;
}, 0);

console.log(result); // undefined

Если callback ничего не возвращает, следующий шаг получит undefined.

Использовать reduce() там, где код становится слишком запутанным

const result = numbers.reduce((acc, value) => {
  // слишком много логики
  return acc;
}, initialValue);

Если решение через map(), filter() или обычный цикл читается проще, иногда лучше выбрать их.

Быстрая памятка

  • reduce() сводит массив к одному итоговому значению
  • ключевая идея метода - accumulator
  • initialValue лучше передавать явно
  • без initialValue пустой массив вызовет ошибку
  • reduce() не меняет исходный массив

Коротко

reduce() - это мощный метод для сворачивания массива в одно значение. Главное, что стоит запомнить: он работает через аккумулятор, обычно требует понятного initialValue и особенно полезен для сумм, подсчётов и сборки новых структур данных.