Для чего используется метод Reduce?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Использование метода Reduce
Reduce — это высокоуровневая функция обработки массивов в JavaScript/TypeScript, которая комбинирует все элементы массива в одно значение, применяя функцию-аккумулятор ко каждому элементу последовательно.
Основное назначение Reduce
- Агрегирование данных — суммирование, подсчёт, объединение элементов
- Трансформация структур — преобразование массива в объект, строку или другую структуру
- Фильтрация и маппирование одновременно — комбинирование нескольких операций в одну итерацию
- Построение сложных структур — индексирование, группировка, статистика
Синтаксис
array.reduce(
(accumulator, currentValue, index, array) => {
// accumulator — результат из предыдущей итерации
// currentValue — текущий элемент массива
// index — индекс текущего элемента (опционально)
// array — исходный массив (опционально)
return updatedAccumulator;
},
initialValue // Начальное значение (опционально)
);
Примеры использования
1. Суммирование элементов
const numbers = [10, 20, 30, 40];
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 100
// Пошагово:
// Итерация 1: acc=0, num=10 → 10
// Итерация 2: acc=10, num=20 → 30
// Итерация 3: acc=30, num=30 → 60
// Итерация 4: acc=60, num=40 → 100
2. Преобразование массива в объект
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' }
];
const usersMap = users.reduce((acc, user) => {
acc[user.id] = user;
return acc;
}, {});
console.log(usersMap);
// { 1: { id: 1, name: 'Alice' }, 2: { id: 2, name: 'Bob' }, ... }
3. Группировка элементов по категориям
const items = [
{ name: 'Apple', category: 'fruit' },
{ name: 'Broccoli', category: 'vegetable' },
{ name: 'Banana', category: 'fruit' },
{ name: 'Carrot', category: 'vegetable' }
];
const grouped = items.reduce((acc, item) => {
if (!acc[item.category]) {
acc[item.category] = [];
}
acc[item.category].push(item.name);
return acc;
}, {});
console.log(grouped);
// {
// fruit: ['Apple', 'Banana'],
// vegetable: ['Broccoli', 'Carrot']
// }
4. Подсчёт частоты элементов
const words = ['cat', 'dog', 'cat', 'bird', 'dog', 'cat'];
const frequency = words.reduce((acc, word) => {
acc[word] = (acc[word] || 0) + 1;
return acc;
}, {});
console.log(frequency);
// { cat: 3, dog: 2, bird: 1 }
5. Вычисление статистики
const scores = [85, 92, 78, 95, 88];
const stats = scores.reduce(
(acc, score) => ({
sum: acc.sum + score,
count: acc.count + 1,
min: Math.min(acc.min, score),
max: Math.max(acc.max, score)
}),
{ sum: 0, count: 0, min: Infinity, max: -Infinity }
);
const average = stats.sum / stats.count;
console.log({ average, min: stats.min, max: stats.max });
// { average: 87.6, min: 78, max: 95 }
6. Склеивание (Flatten) вложенных массивов
const nested = [[1, 2], [3, 4], [5, 6]];
const flat = nested.reduce(
(acc, arr) => acc.concat(arr),
[]
);
console.log(flat); // [1, 2, 3, 4, 5, 6]
7. Цепь преобразований (Compose)
const value = 5;
const transformers = [
(x: number) => x * 2, // 5 * 2 = 10
(x: number) => x + 3, // 10 + 3 = 13
(x: number) => x / 2 // 13 / 2 = 6.5
];
const result = transformers.reduce(
(acc, fn) => fn(acc),
value
);
console.log(result); // 6.5
Reduce vs Map/Filter/ForEach
Когда использовать Reduce:
const data = [
{ name: 'Product A', price: 100, quantity: 2 },
{ name: 'Product B', price: 50, quantity: 3 }
];
// ❌ Несколько проходов (менее эффективно)
const total = data
.map(p => p.price * p.quantity)
.filter(p => p > 100)
.reduce((sum, price) => sum + price, 0);
// ✅ Один проход (более эффективно)
const total = data.reduce((acc, item) => {
const itemTotal = item.price * item.quantity;
return itemTotal > 100 ? acc + itemTotal : acc;
}, 0);
Практические примеры в Node.js
Обработка логов
const logs = [
{ level: 'info', timestamp: '10:00', message: 'App started' },
{ level: 'error', timestamp: '10:05', message: 'Connection failed' },
{ level: 'info', timestamp: '10:06', message: 'Reconnected' },
{ level: 'error', timestamp: '10:07', message: 'Timeout' }
];
const summary = logs.reduce((acc, log) => {
if (!acc[log.level]) {
acc[log.level] = [];
}
acc[log.level].push(log.message);
return acc;
}, {});
console.log(summary);
// {
// info: ['App started', 'Reconnected'],
// error: ['Connection failed', 'Timeout']
// }
Вычисление суммы заказов
const orders = [
{ id: 1, items: [{price: 30}, {price: 50}] },
{ id: 2, items: [{price: 25}, {price: 40}, {price: 35}] }
];
const totalRevenue = orders.reduce((total, order) => {
const orderSum = order.items.reduce((sum, item) => sum + item.price, 0);
return total + orderSum;
}, 0);
console.log(totalRevenue); // 180
Важные моменты
1. Нужно вернуть аккумулятор
// ❌ Неправильно: забыли return
const result = numbers.reduce((acc, num) => {
acc += num;
// missing return!
});
// ✅ Правильно
const result = numbers.reduce((acc, num) => {
return acc + num;
}, 0);
// ✅ Или со стрелкой одной строкой
const result = numbers.reduce((acc, num) => acc + num, 0);
2. Всегда указывайте начальное значение
const nums = [1, 2, 3];
// ❌ Может быть неправильно если массив пустой
const sum = nums.reduce((a, b) => a + b); // undefined если массив пустой
// ✅ Правильно
const sum = nums.reduce((a, b) => a + b, 0); // 0 если массив пустой
Производительность
Reduce проходит массив один раз — O(n) сложность. Это эффективнее чем цепочка map → filter → reduce которая имеет O(3n):
const arr = Array.from({length: 1000000}, (_, i) => i);
// Медленнее: три прохода
const result1 = arr
.map(x => x * 2)
.filter(x => x > 500)
.reduce((a, b) => a + b, 0);
// Быстрее: один проход
const result2 = arr.reduce((acc, x) => {
if (x * 2 > 500) {
return acc + (x * 2);
}
return acc;
}, 0);
Вывод
Reduce — это мощный инструмент функционального программирования:
- Универсален — преобразует массивы в любую структуру
- Эффективен — один проход по данным
- Функциональный стиль — декларативный код без побочных эффектов
- Готов к работе с сложными структурами — группировка, статистика, индексирование
Это один из ключевых методов, который каждый Node.js разработчик должен освоить для написания чистого и эффективного кода.