Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

map, filter и reduce

Большинство задач с массивами сводятся к трём действиям: изменить каждый элемент, отобрать подходящие или посчитать итог. Для них есть методы map(), filter() и reduce(). Код с ними короче цикла, и по имени метода сразу видно, что он делает.

map — преобразовать каждый элемент

map() вызывает функцию для каждого элемента и собирает её результаты в новый массив той же длины:

const numbers = [1, 2, 3];
 
const doubled = numbers.map((n) => n * 2);
 
console.log(doubled.join(', ')); // 2, 4, 6

Исходный массив numbers не меняется — map() всегда возвращает новый.

filter — отобрать подходящие

filter() оставляет только те элементы, для которых функция вернула true. Такую функцию-проверку называют условием или предикатом:

const numbers = [5, 12, 8, 20];
 
const big = numbers.filter((n) => n > 10);
 
console.log(big.join(', ')); // 12, 20

Если ни один элемент не подошёл, получится пустой массив.

reduce — свести к одному значению

reduce() проходит по массиву и накапливает результат. Функция получает накопленное значение (его часто называют sum или acc) и очередной элемент, а второй аргумент reduce() — начальное значение:

const prices = [100, 250, 400];
 
const total = prices.reduce((sum, price) => sum + price, 0);
 
console.log(total); // 750

На первом шаге sum равно 0, на втором — 100, на третьем — 350, и в конце получается 750.

Массив объектов

Чаще всего эти методы работают с массивами объектов. Объект — это значение в фигурных скобках, которое хранит данные под именами: product.title читает свойство title. Подробно объекты разобраны в следующей главе.

const products = [
  { title: 'Чай', price: 5 },
  { title: 'Кофе', price: 12 },
];
 
const titles = products.map((product) => product.title);
 
console.log(titles.join(', ')); // Чай, Кофе

Цепочка методов

map() и filter() возвращают массив, поэтому следующий метод можно вызвать сразу после предыдущего:

const orders = [
  { total: 500, paid: true },
  { total: 300, paid: false },
  { total: 200, paid: true },
];
 
const paidSum = orders
  .filter((order) => order.paid)
  .map((order) => order.total)
  .reduce((sum, total) => sum + total, 0);
 
console.log(paidSum); // 700

Цепочку читают сверху вниз: оплаченные заказы, их суммы, общий итог.

Частая ошибка

Если тело стрелочной функции взято в фигурные скобки, значение нужно вернуть через return. Без него функция возвращает undefined:

const numbers = [1, 2, 3];
 
const wrong = numbers.map((n) => { n * 2; });
const right = numbers.map((n) => { return n * 2; });
 
console.log(wrong[0]);         // undefined
console.log(right.join(', ')); // 2, 4, 6

В короткой записи без скобок, (n) => n * 2, return подразумевается сам.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.