Методы перебора массива (map, filter, reduce)
Язык JavaScript оказывает явное предпочтение массивам перед другими структурами данных. У них много удобных специфических фишек, например, целый набор перебирающих методов: map
, filter
, reduce
.
map
Метод map()
создаёт новый массив с результатом вызова указанной функции⚙️ для каждого элемента массива.
Синтаксис
let new_array = arr.map(function callback( currentValue[, index[, array]]) {
// Возвращает элемент для new_array
}[, thisArg])
Метод map
вызывает переданную функцию⚙️ callback
один раз для каждого элемента, в порядке их появления и конструирует новый массив из результатов её вызова. Функция⚙️ callback
вызывается только для индексов массива, имеющих присвоенные значения, включая undefined
. Она не вызывается для пропущенных элементов массива (то есть для индексов, которые никогда не были заданы, были удалены или им никогда не было присвоено значение).
Функция⚙️ callback
вызывается с тремя аргументами:
- значением элемента,
- индексом элемента
- и массивом, по которому осуществляется проход.
Если в метод map
был передан параметр thisArg
, при вызове callback
он будет использоваться в качестве значения this
. В противном случае в качестве значения this
будет использоваться значение undefined
. В конечном итоге значение this
, наблюдаемое из функции⚙️ callback
, определяется согласно обычным правилам определения this
, видимого из функции⚙️.
Метод map
не изменяет массив, для которого он был вызван (хотя функция⚙️ может это делать!).
Диапазон элементов, обрабатываемых методом map
, устанавливается до первого вызова функции⚙️ callback
. Элементы, добавленные в массив после начала выполнения метода map
, не будут посещены функцией⚙️ callback
. Если существующие элементы массива изменяются функцией⚙️ callback
, их значения, переданные в функцию⚙️, будут значениями на тот момент времени, когда метод map
посетит их. Удалённые элементы посещены не будут.
Примеры:
простой пример
У вас есть массив со множеством объектов, каждый из которых представляет отдельного человека. Тут может быть очень много данных: имя, возраст, цвет волос и любимый персонаж из кинематографа, но в данный момент всё это не требуется – вы хотите получить только массив паспортных номеров этих людей, чтобы выдать им всем пропуска на конференцию.
В определенных случаях вам может понадобится отобразить массив объектов с выбранными ключами в виде строки :
Создание массива значений Фаренгейта из массива значений Цельсия:
Пример с обработкой каждого элемента массива заданной формулой :
Отображение массива чисел с использованием функции, содержащей аргумент :
filter
Метод filter()
создаёт новый массив со всеми элементами, прошедшими проверку, задаваемую в передаваемой функции⚙️.
Результатом работы filter
всегда является массив. Если функция⚙️ для элемента возвращает true
(или любое "правдивое" значение), этот элемент попадает в результат, иначе – не попадает.
Синтаксис
let newArray = arr.filter(function callback(element[, index, [array]])[, thisArg])
Описание
Метод filter()
вызывает переданную функцию⚙️ callback
один раз для каждого элемента, присутствующего в массиве, и конструирует новый массив со всеми значениями, для которых функция⚙️ callback
вернула true
или значение, становящееся true
при приведении в boolean
. Функция⚙️ callback
вызывается только для индексов массива, имеющих присвоенные значения; она не вызывается для индексов, которые были удалены или им значения никогда не присваивались. Элементы массива, не прошедшие проверку функцией⚙️ callback
, просто пропускаются и не включаются в новый массив.
Функция⚙️ callback
вызывается с тремя аргументами:
- значение элемента;
- индекс элемента;
- массив, по которому осуществляется проход.
Если в метод filter()
был передан параметр thisArg
, при вызове функции⚙️ он будет использоваться в качестве значения this
. В противном случае в качестве значения this
будет использоваться значение undefined
. В конечном итоге значение this
, наблюдаемое из функции⚙️, определяется согласно обычным правилам определения this
, видимого из функции⚙️.
Метод filter()
не изменяет массив, для которого он был вызван.
Диапазон элементов, обрабатываемых методом filter()
, устанавливается до первого вызова функции⚙️ callback
. Элементы, добавленные в массив после начала выполнения метода filter()
, не будут посещены функцией⚙️ callback
. Если существующие элементы массива изменятся, значения, переданные в функцию⚙️ callback
, будут значениями на тот момент времени, когда метод filter()
посетит их. Удалённые элементы посещены не будут.
Пример
Отфильтровывание всех маленьких значений
Следующий пример использует filter()
для создания отфильтрованного массива, все элементы которого больше или равны value
, а все меньшие value
удалены.
reduce
Метод reduce
также запускается в контексте массива и вызывает функцию⚙️ для каждого элемента, но помимо этого, он аккумулирует результаты всех вызовов в одно значение. Этим поведением можно управлять.
reduce
предназначен не для того, чтобы изменять элементы коллекции, как map
. Его задача – подсчитать "сумму" всех элементов тем или иным способом, и вернуть ее.
Результирующим значением может быть что угодно: число, строка, объект, массив – все зависит от задачи, которую решает JavaScript разработчик.
Метод reduce
принимает 2 параметра:
- функция, как и
map
, который будет вызван последовательно для каждого элемента коллекции; - начальное значение аккумулятора.
В функции⚙️ тоже 2 аргумента:
- первый – это накопленное значение (аккумулятор);
- непосредственно элемент массива.
Синтаксис
array.reduce(function callback[, initialValue])
Описание
Метод reduce()
выполняет функцию⚙️ callback
один раз для каждого элемента, присутствующего в массиве, за исключением пустот, принимая четыре аргумента: начальное значение (или значение от предыдущего вызова callback
), значение текущего элемента, текущий индекс и массив, по которому происходит итерация.
При первом вызове функции⚙️, параметры accumulator
и currentValue
могут принимать одно из двух значений. Если при вызове reduce()
передан аргумент initialValue
, то значение accumulator
будет равным значению initialValue
, а значение currentValue
будет равным первому значению в массиве. Если аргумент initialValue
не задан, то значение accumulator
будет равным первому значению в массиве, а значение currentValue
будет равным второму значению в массиве.
Если массив пустой и аргумент initialValue
не указан, будет брошено исключение TypeError
. Если массив состоит только из одного элемента (независимо от его положения в массиве) и аргумент initialValue
не указан, или если аргумент initialValue
указан, но массив пустой, то будет возвращено одно это значение, без вызова функции⚙️ callback
.
Начальное значение аккумулятора
Разберемся с начальным значением. В примере оно равно 0
, так как мы считаем численное значение – сумму возрастов. На месте нуля может быть любое другое число/строка (пустая или нет)/объект/массив – любое значение, с которого вы начинаете аккумуляцию. Для примера объединим имена всех друзей в одну строчку :
Здесь исходным значением послужила строка "Friends:"
, к которой постепенно добавились имена всех друзей.
Если вы не указываете исходное значение явно, им неявно становится первый 1️⃣ элемент массива. В этом случае функция⚙️ для него уже не вызывается.
Пример
Суммирование всех значений в массиве:
И тоже самое в одну строчку кода:
chaining
Программирование на JavaScript поддерживает удобный паттерн чейнинг (chaining
) – объединение нескольких функций⚙️ в одну цепочку с последовательной передачей результата.
Все три разобранных метода вызываются в контексте массива, а два 2️⃣ из них еще и возвращают массив. Таким образом, их очень легко объединить.
Например, посчитаем общий возраст всех мальчиков :
Или соберем номера паспортов девочек, чтобы купить им билеты на самолет до Лас-Вегаса :
Заключение
С использованием этих замечательных функций⚙️ код стало читать удобнее. Итак, ниже приведен список статей, в которых более подробна рассмотрена эта тема.
Проблемы?
Пишите в Telegram или ВКонтакте, а также подписывайтесь на наши новости
Вопросы:
Функция, вызываемая для каждого элемента массива?
currentValue
array
callback
Метод, который создаёт новый массив с результатом вызова указанной функции для каждого элемента массива:
map
filter
reduce
Результирующим значением метода reduce
может выступать:
- Число
- Массив
- Что угодно
Суммирование всех значений в массиве достигается методом:
map
filter
reduce
Необязательный параметр или значение, используемое в качестве this
при вызове функции callback
:
array
index
thisArg
Метод, который создаёт новый массив со всеми элементами, прошедшими проверку, задаваемую в передаваемой функции:
map
filter
reduce
Объединение нескольких функций в одну цепочку с последовательной передачей результата:
- unity
- chaining
- merger
Для того чтобы понять, на сколько вы усвоили этот урок, пройдите тест в мобильном приложении нашей школы по этой теме.
Ссылки:
- Упрости свой JavaScript – используй map, reduce и filter
- 15 Полезных javascript примеров map(), reduce() и filter()
- Array.prototype.map()
- Array.prototype.filter()
- Array.prototype.reduce()
Contributors ✨
Thanks goes to these wonderful people (emoji key):
AlisaNasibullina | Dmitriy Vasilev 💵 | Resoner2005 🐛 🎨 🖋 | Navernoss 🖋 🐛 🎨 |