Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Метод reduce() у масиві». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`reduce()` послідовно зводить масив до одного підсумкового значення: числа, рядка, об'єкта чи іншого масиву.** На кожній ітерації колбек отримує акумулятор і поточний елемент, а те, що він повертає, стає акумулятором для наступного кроку. Початкове значення передається другим аргументом і задає тип результату. ```javascript const numbers = [1, 2, 3, 4]; const sum = numbers.reduce((acc, num) => acc + num, 0); console.log(sum); // 10 ``` **Ключове:** завжди вказуйте `initialValue`, бо без нього `reduce()` на порожньому масиві кидає `TypeError`, а колбек обов'язково має повертати новий акумулятор.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`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()`.** Такий код читається важче, ніж послідовність простих методів, і не дає жодного виграшу.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.