Методы массивов
map, filter, reduce, find и цепочки вызовов.
Обновлено
Что такое массив
Массив (array) — упорядоченный список значений. У каждого значения есть позиция, нумерация с 0 (индекс).
const fruits = ['яблоко', 'груша', 'слива']
fruits[0] // 'яблоко'
fruits.at(-1) // 'слива' — последний
fruits.length // 3Массив может содержать что угодно: числа, объекты, другие массивы. На практике почти всегда работают со списками объектов (товары, пользователи, заказы).
Два семейства методов
Самое важное различие:
| Меняют массив (мутация) | Возвращают новый массив | |
|---|---|---|
| Методы | push, pop, shift, unshift, splice, sort, reverse, fill |
map, filter, slice, concat, toSorted, toReversed, with, [...arr] |
| В состоянии React | ✗ — интерфейс не обновится | ✓ |
Правило: в коде интерфейса предпочитайте методы, которые возвращают новый массив.
Методы преобразования — что делает каждый
| Метод | Получает | Возвращает | На какой вопрос отвечает |
|---|---|---|---|
map(fn) |
каждый элемент | новый массив той же длины | «преврати каждый элемент во что-то другое» |
filter(fn) |
каждый элемент | новый массив, короче или равный | «оставь только элементы, которые...» |
reduce(fn, start) |
аккумулятор + элемент | одно значение (число, объект, массив) | «собери всё в один результат» |
find(fn) |
каждый элемент | первый найденный или undefined |
«какой первый, который...» |
findIndex(fn) |
каждый элемент | индекс или -1 |
«где находится...» |
some(fn) |
каждый элемент | true, если хотя бы один подходит |
«есть ли хоть один, который...» |
every(fn) |
каждый элемент | true, если все подходят |
«все ли...» |
includes(x) |
значение | true / false |
«содержит ли значение...» |
forEach(fn) |
каждый элемент | undefined |
только побочные эффекты (лог, отправка) |
flatMap(fn) |
каждый элемент | новый массив, сглаженный на один уровень | «каждый элемент становится несколькими» |
const products = [
{ name: 'Laptop', price: 4000, inStock: true },
{ name: 'Mouse', price: 100, inStock: false },
{ name: 'Monitor', price: 1200, inStock: true },
]
products.map(p => p.name) // ['Laptop', 'Mouse', 'Monitor']
products.filter(p => p.inStock) // Laptop, Monitor
products.find(p => p.price < 500) // { name: 'Mouse', ... }
products.some(p => !p.inStock) // true
products.reduce((sum, p) => sum + p.price, 0) // 5300map или forEach
map |
forEach |
|
|---|---|---|
| Возвращает | новый массив | ничего |
| Используется, чтобы | получить преобразованные данные (включая JSX в React) | сделать что-то с каждым элементом |
arr.forEach(x => result.push(f(x))) — это плохо написанный map.
reduce — по шагам
[10, 20, 30].reduce((acc, n) => acc + n, 0)
// шаг 1: acc = 0, n = 10 → 10
// шаг 2: acc = 10, n = 20 → 30
// шаг 3: acc = 30, n = 30 → 60Используйте для сумм, группировок, сборки объекта. Если читать становится трудно, for...of вполне допустим.
Цепочки
Методы, возвращающие массив, можно соединять в цепочку — преобразование читается сверху вниз:
const total = cart
.filter(item => item.inStock)
.map(item => item.price * item.qty)
.reduce((sum, x) => sum + x, 0)Сортировка — ловушки
[10, 9, 100].sort() // [10, 100, 9] — сортирует как ТЕКСТ!
[10, 9, 100].toSorted((a, b) => a - b) // [9, 10, 100] ✓ новый, числовой
users.toSorted((a, b) => a.name.localeCompare(b.name, 'ru')) // правильный алфавитный порядок с ёSpread и деструктуризация
const [first, second, ...rest] = [1, 2, 3, 4] // first=1, second=2, rest=[3,4]
const merged = [...a, ...b] // объединение
const copy = [...arr] // (поверхностная) копияКоротко
- Массив = упорядоченный список с индексами от 0.
mapпреобразует,filterотбирает,reduceобъединяет,findищет,some/everyпроверяют.- В интерфейсе используйте методы, возвращающие новый массив;
sort— с компаратором.