Skip to main content

Метод reduce() у масиві

reduce() це один із найпотужніших і найуніверсальніших методів роботи з масивами в JavaScript: він послідовно зводить (reduce) масив до одного значення. Цим значенням може бути число, рядок, об'єкт, новий масив чи будь-яка інша структура, тому reduce() закриває майже всі задачі агрегації даних.

Теорія

TL;DR

  • reduce() проходить масив зліва направо і накопичує результат в акумуляторі.
  • Колбек має сигнатуру (accumulator, currentValue, index, array) і мусить повертати новий акумулятор.
  • Другий аргумент initialValue задає стартове значення і тип результату.
  • Без initialValue першим акумулятором стає нульовий елемент, а порожній масив дає TypeError.
  • Для простого перетворення елементів краще map(), для відбору filter(), а reduce() беріть тоді, коли потрібен один підсумок.

Швидкий приклад

javascript
const numbers = [1, 2, 3, 4]; const sum = numbers.reduce((acc, num) => acc + num, 0); console.log(sum); // 10

Покроково це виглядає так:

  1. acc = 0 (початкове значення)
  2. 0 + 1 -> 1
  3. 1 + 2 -> 3
  4. 3 + 3 -> 6
  5. 6 + 4 -> 10

Синтаксис і параметри

javascript
const result = array.reduce((accumulator, currentValue, index, array) => { return newAccumulatorValue; }, initialValue);
АргументОпис
accumulatorнакопичене значення, тобто те, що повернула попередня ітерація
currentValueпоточний елемент масиву
indexіндекс поточного елемента
arrayсам масив, над яким викликано метод
initialValueпочаткове значення акумулятора, формально необов'язкове, але вказувати його дуже бажано

Типові сценарії використання

Підрахунок кількості елементів за умовою. reduce() часто застосовують для агрегації: підрахунків, статистики, об'єднань.

javascript
const users = [ { name: 'Tim', age: 25 }, { name: 'Alex', age: 17 }, { name: 'John', age: 30 } ]; const adultsCount = users.reduce((acc, user) => { return user.age >= 18 ? acc + 1 : acc; }, 0); console.log(adultsCount); // 2

Перетворення масиву на об'єкт. Дуже зручно, коли дані потрібно перекласти в іншу структуру, наприклад у словник для швидкого пошуку.

javascript
const fruits = ['apple', 'banana', 'cherry']; const fruitMap = fruits.reduce((acc, fruit, index) => { acc[index] = fruit; return acc; }, {}); console.log(fruitMap); // { 0: 'apple', 1: 'banana', 2: 'cherry' }

Згортання масиву об'єктів в одне число. Класика для кошика чи звіту.

javascript
const products = [ { price: 10 }, { price: 20 }, { price: 30 } ]; const total = products.reduce((acc, item) => acc + item.price, 0); console.log(total); // 60

Початкове значення і порожній масив

Якщо initialValue не вказати, акумулятором на першій ітерації стає перший елемент масиву, а обхід починається з другого.

javascript
const arr = [1, 2, 3]; const sum = arr.reduce((acc, num) => acc + num); console.log(sum); // 6

Тут acc на першій ітерації дорівнює 1 (перший елемент), а currentValue дорівнює спочатку 2, потім 3.

Якщо масив порожній і початкового значення немає, метод кидає помилку:

javascript
[].reduce((acc, x) => acc + x); // TypeError: Reduce of empty array with no initial value

Саме тому початкове значення варто задавати завжди, особливо коли масив приходить із мережі і може виявитися порожнім.

Коли брати reduce(), а коли інші методи

МетаЧи підходить reduce()
Сума або добуток чиселТак
Підрахунок статистики або кількостіТак
Перетворення масиву на об'єктТак
Конкатенація рядків або масивівТак
Перетворення кожного елементаНі, краще map()
Відбір елементівНі, краще filter()

Порівняння з сусідніми методами перебору:

МетодЩо робитьЩо повертаєЧи може перервати цикл
forEach()перебирає елементиundefinedні
map()перетворює елементиновий масивні
filter()відбирає елементиновий масивні
find()знаходить перший відповідний елементелемент або undefinedтак
reduce()зводить увесь масив до одного значеннябудь-який тип: число, рядок, об'єкттак, через логіку в колбеку

Формула для запам'ятовування: arr.reduce((acc, elem) => новеЗначення, початковеЗначення).

Типові помилки

1. Забутий return у тілі колбека. Фігурні дужки стрілочної функції скасовують неявне повернення, тож акумулятор стає undefined.

javascript
arr.reduce((acc, num) => { acc + num }, 0); // undefined

Правильно:

javascript
arr.reduce((acc, num) => { return acc + num }, 0);

2. Невідповідний тип початкового значення. Якщо елементи є рядками, а акумулятор числом, спрацює конкатенація замість додавання.

javascript
['1', '2', '3'].reduce((acc, n) => acc + n, 0); // '0123', це рядок

Правильно, з явним перетворенням:

javascript
['1', '2', '3'].reduce((acc, n) => acc + Number(n), 0); // 6

3. Мутація зовнішніх даних. Акумулятор-об'єкт можна змінювати, бо він створений усередині виклику, але змінювати вихідні елементи масиву не варто: це робить результат непередбачуваним.

4. reduce() там, де вистачило б map() або filter(). Такий код читається важче, ніж послідовність простих методів, і не дає жодного виграшу.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.