map, filter, reduce — функции высших порядков
ИИ почти никогда не пишет `for (let i = 0; i < arr.length; i++)`. Вместо этого — `arr.map(...)`, `arr.filter(...)`, `arr.reduce(...)`. Это короче, надёжнее, и сразу видно что код делает. Разберём все три и научимся читать.
map — преобразовать каждый элемент
arr.map(fn) — пробегает по массиву, для каждого элемента вызывает функцию, собирает результаты в НОВЫЙ массив той же длины. Не трогает оригинал. Используют когда нужно «преобразовать каждый» — например взять имена пользователей: users.map(u => u.name). Или удвоить числа: nums.map(n => n * 2).
filter — оставить только подходящие
arr.filter(fn) — для каждого элемента вызывает функцию, возвращает НОВЫЙ массив только из тех, где функция вернула true. Используют для «отфильтровать»:
(только взрослые). tasks.filter(t => !t.done) (только незавершённые). Если ничего не подошло — пустой массив.
reduce — свернуть массив в одно значение
arr.reduce(fn, начальное) — пробегает по массиву, аккумулируя результат. На каждом шаге функция получает аккумулятор и текущий элемент, возвращает новый аккумулятор. Используется для сумм, счётчиков, преобразований в объект. Самый сложный из трёх — но самый мощный.
Цепочки — сила всех вместе
Эти функции возвращают массив, поэтому их можно цеплять. Хочешь сумму цен взрослых пользователей?
Каждый шаг читается отдельно: «фильтр взрослые → взять цены → сложить». Сравни с одним для-циклом — намного чище.
const товары = [
{ имя: 'Молоко', цена: 95, доступен: true },
{ имя: 'Хлеб', цена: 45, доступен: false },
{ имя: 'Сыр', цена: 280, доступен: true },
{ имя: 'Йогурт', цена: 65, доступен: true },
];
// === MAP — преобразуем каждый ===
const имена = товары.map(t => t.имя);
// ['Молоко', 'Хлеб', 'Сыр', 'Йогурт']
const сКидкой = товары.map(t => ({
...t,
цена: t.цена * 0.9, // -10%
}));
// новый массив объектов с уменьшенной ценой
// === FILTER — отбираем по условию ===
const доступные = товары.filter(t => t.доступен);
// [Молоко, Сыр, Йогурт]
const дешёвые = товары.filter(t => t.цена < 100);
// [Молоко, Хлеб, Йогурт]
// === REDUCE — сворачиваем в одно значение ===
const сумма = товары.reduce((acc, t) => acc + t.цена, 0);
// 485 — сумма всех цен
// Сгруппировать в объект:
const поДоступности = товары.reduce((acc, t) => {
const ключ = t.доступен ? 'есть' : 'нет';
acc[ключ] = acc[ключ] || [];
acc[ключ].push(t);
return acc;
}, {});
// { есть: [Молоко, Сыр, Йогурт], нет: [Хлеб] }
// === ЦЕПОЧКА — сила вместе ===
const суммаДешёвыхДоступных = товары
.filter(t => t.доступен) // есть в наличии
.filter(t => t.цена < 100) // дешёвые
.reduce((sum, t) => sum + t.цена, 0); // сумма
// 160 (Молоко 95 + Йогурт 65)
// === Сравни с обычным циклом ===
let сумма_обычно = 0;
for (let i = 0; i < товары.length; i++) {
if (товары[i].доступен && товары[i].цена < 100) {
сумма_обычно += товары[i].цена;
}
}
// Тот же результат, но 4 строки против 3
// и читать сложнее — нужно строить картинку в головеmap / filter / reduce — три инструмента которые покрывают 80% задач с массивами