Методы массивов: map, filter, reduce

map, filter, reduce — высокоуровневые методы массивов для трансформации данных: map преобразует каждый элемент, filter отбирает по условию, reduce сворачивает массив в одно значение.

Зачем нужно

Эти три метода — основа функционального стиля в JavaScript. Они позволяют описывать преобразования данных декларативно (что нужно получить), а не императивно (как это делать шаг за шагом), делают код чище, легче тестировать и читать.

Где используется

  • Рендеринг списков (каждый элемент → JSX/HTML)
  • Фильтрация данных по критерию
  • Агрегация: сумма, группировка, индексирование
  • Цепочки трансформаций данных из API

map — преобразование

// Возвращает НОВЫЙ массив той же длины
const prices = [100, 200, 300, 400];

const withTax = prices.map(price => price * 1.2);
console.log(withTax);  // [120, 240, 360, 480]
console.log(prices);   // [100, 200, 300, 400] — оригинал не изменён

// Преобразование объектов
const users = [
  { id: 1, firstName: 'Иван',  lastName: 'Иванов' },
  { id: 2, firstName: 'Мария', lastName: 'Петрова' },
];

const names = users.map(u => `${u.firstName} ${u.lastName}`);
// ['Иван Иванов', 'Мария Петрова']

// Callback получает (element, index, array)
const indexed = ['a', 'b', 'c'].map((el, i) => `${i}: ${el}`);
// ['0: a', '1: b', '2: c']

filter — отбор элементов

// Возвращает НОВЫЙ массив с элементами, прошедшими проверку
const numbers = [1, 2, 3, 4, 5, 6, 7, 8];

const evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4, 6, 8]

// Фильтрация объектов
const activeUsers = users.filter(u => u.active && u.age >= 18);

// Удаление дубликатов простых значений
const unique = (arr) => arr.filter((el, i, arr) => arr.indexOf(el) === i);
// Или: [...new Set(arr)]

reduce — свёртка в значение

// reduce(callback, initialValue)
// callback(accumulator, currentValue, index, array)
const nums = [1, 2, 3, 4, 5];

// Сумма
const sum = nums.reduce((acc, n) => acc + n, 0);
console.log(sum); // 15

// Максимум
const max = nums.reduce((acc, n) => n > acc ? n : acc, -Infinity);
console.log(max); // 5

// Группировка
const orders = [
  { status: 'done', amount: 100 },
  { status: 'pending', amount: 200 },
  { status: 'done', amount: 300 },
];

const grouped = orders.reduce((acc, order) => {
  const key = order.status;
  acc[key] = acc[key] || ;
  acc[key].push(order);
  return acc;
}, {});
// { done: [{...}, {...}], pending: [{...}] }

// Плоский массив из массива массивов
const flat = [[1, 2], [3, 4], [5]].reduce((acc, arr) => [...acc, ...arr], );
console.log(flat); // [1, 2, 3, 4, 5]

Цепочки

const products = [
  { name: 'Яблоко',  category: 'фрукты', price: 50 },
  { name: 'Морковь', category: 'овощи',  price: 30 },
  { name: 'Груша',   category: 'фрукты', price: 80 },
];

const totalFruitPrice = products
  .filter(p => p.category === 'фрукты')  // [Яблоко, Груша]
  .map(p => p.price)                      // [50, 80]
  .reduce((sum, price) => sum + price, 0); // 130

console.log(totalFruitPrice); // 130

Частые ошибки

  • Не возвращать значение в map — стрелочная функция без {} возвращает неявно; с {} нужен явный return.
  • reduce без начального значения — при пустом массиве .reduce(fn) бросает TypeError; всегда передавайте initialValue.
  • Мутировать элементы в mapmap должен возвращать новые значения, не изменять исходные объекты; используйте {...el, modified: true}.

Связанные темы

Ресурсы