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 и особенно полезен для сумм, подсчётов и сборки новых структур данных.