Modern JS Cheatsheet / Памятка по современному JavaScript: Методы массивов - map / filter / reduce
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
### Методы массивов - map / filter / reduce wizjer 29.09.17 в 03:24 |
|
|
*Map*, *filter* и *reduce* это методы массивов, пришедшие из парадигмы [*функционального программирования*](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0). wizjer 29.09.17 в 06:21 |
||
|
Перечислю их: wizjer 29.09.17 в 08:30 |
||
|
- **Array.prototype.map()** берет массив, делает что-то с его элементами и возвращается массив трансформированных элементов. wizjer 29.09.17 в 08:29 |
||
|
Я рекомендую пользоваться ими как можно чаще, следуя принципам функционального программирования, потому что они лаконичные, элегантные и их можно комбинировать. wizjer 29.09.17 в 08:37 |
+4 | |
|
Вооружившись этими тремя методами, вы можете обойтись без использования *for* и *forEach* в большинстве ситуаций. Когда в следующий раз соберётесь запустить цикл *for*, попробуйте решить задачу с помощью *map*, *filter* и *reduce*. Поначалу это будет трудно, потому что вам придётся научиться мыслить по-другому, но, разобравшись один раз, вы сможете применять эти методы без особых усилий. wizjer 29.09.17 в 08:45 |
||
|
#### Пример кода wizjer 29.09.17 в 08:46 |
||
|
```js wizjer 29.09.17 в 08:46 |
||
|
Давайте посчитаем сумму баллов всех студентов, которые набрали больше 10 баллов, используя *map*, *filter* и *reduce*: wizjer 29.09.17 в 08:48 |
||
|
```js wizjer 29.09.17 в 08:32 |
||
|
const aboveTenSum = students wizjer 29.09.17 в 11:03 |
||
|
console.log(aboveTenSum) // 44 -- 10 (Коля) + 15 (Ваня) + 19 (Юля), оценка Наташи меньше 10 и была проигнорирована wizjer 29.09.17 в 11:04 |
||
|
#### Объяснение wizjer 29.09.17 в 11:04 |
||
|
Давайте использовать в качестве примера следующий массив: wizjer 29.09.17 в 11:04 |
||
|
```js wizjer 29.09.17 в 08:33 |
||
|
##### Array.prototype.map() wizjer 29.09.17 в 11:04 |
||
|
```js wizjer 29.09.17 в 08:33 |
||
|
Что же здесь происходит? Мы применяем к массиву *numbers* метод .map, который взаимодействует с каждым элементом массива и передаёт его в нашу функцию. Цель функции произвести расчёт и вернуть новое значение, чтобы map мог подставить его вместо переданного в функцию. wizjer 29.09.17 в 11:09 |
||
|
Давайте даже вынесем функцию из массива, чтобы было понятнее, что происходит: wizjer 29.09.17 в 11:11 |
||
|
```js wizjer 29.09.17 в 08:33 |
||
|
```numbers.map(doubleN)``` создаёт ```[doubleN(0), doubleN(1), doubleN(2), doubleN(3), doubleN(4), doubleN(5), doubleN(6)]``` что равняется ```[0, 2, 4, 6, 8, 10, 12]```. wizjer 30.09.17 в 08:46 |
||
|
> **Примечание:** Если вы не хотите возвращать новый массив и просто хотите перебрать массив, совершая некоторые действия, то, возможно, вы захотите использовать просто for / forEach вместо метода map. wizjer 30.09.17 в 08:51 |
||
|
##### Array.prototype.filter() wizjer 30.09.17 в 08:51 |
||
|
```js wizjer 30.09.17 в 08:55 |
||
|
Мы применяем .filter к массиву *numbers*, filter взаимодействует с каждым элементом массива и передаёт его в нашу функцию. Функция возвращает булево значение, что определяет, будет ли элемент сохранён в массиве. Затем filter возвращает массив отфильтрованных значений. wizjer 30.09.17 в 08:59 |
||
|
##### Array.prototype.reduce() wizjer 30.09.17 в 08:59 |
||
|
Цель метода reduce заключается в том, чтобы вычислить на основе массива какое-то одно значение. Какие именно вычисления метод произведет с элементами зависит только от вас. wizjer 30.09.17 в 09:01 |
||
|
```js wizjer 30.09.17 в 09:02 |
||
|
console.log(sum) //21 wizjer 29.09.17 в 08:34 |
||
|
Также как методы .map и .filter, метод .reduce применяется к массиву и в качестве первого параметра принимает функцию. wizjer 30.09.17 в 09:04 |
+1 | |
|
На этот раз, впрочем, кое-что изменилось: wizjer 30.09.17 в 09:04 |
||
|
- .reduce принимает два параметра wizjer 30.09.17 в 09:04 |
||
|
Первый параметр это функция, которая будет вызываться на каждом шаге цикла. wizjer 30.09.17 в 09:04 |
||
|
Второй параметр это значение аккумулирующей переменной (*acc* в нашем случае) на первом шаге цикла (чтобы разобраться, читайте далее) wizjer 30.09.17 в 09:06 |
||
|
- Параметры функции wizjer 30.09.17 в 09:14 |
||
|
Функция, которую вы передаёте в качестве первого параметра метода .reduce принимает два параметра. Первый параметр это аккумулирующая переменная (*acc* в нашем примере), второй параметр — текущий элемент. wizjer 02.10.17 в 05:22 |
||
|
Аккумулирующая переменная равна значению, возвращённому нашей функцией на **предыдущем** шаге цикла. В самом начале каждого цикла *acc* равна значению, которое вы передали в качестве второго параметра .reduce. wizjer 02.10.17 в 05:24 |
||
|
###### На первом шаге wizjer 02.10.17 в 05:24 |
||
|
```acc = 0``` потому что мы передали 0 в качестве второго параметра метода reduce wizjer 02.10.17 в 05:25 |
||
|
```n = 0``` это первый элемент массива *number* wizjer 02.10.17 в 05:25 |
||
|
Функция возвращает *acc* + *n* --> 0 + 0 --> 0 wizjer 02.10.17 в 05:25 |
||
|
###### На втором шаге wizjer 02.10.17 в 05:25 |
||
|
```acc = 0``` потому что это значение функция вернула на предыдущем шаге wizjer 02.10.17 в 05:26 |
||
|
```n = 1``` это второй элемент массива *number* wizjer 02.10.17 в 05:26 |
||
|
Функция возвращает *acc* + *n* --> 0 + 1 --> 1 wizjer 02.10.17 в 05:26 |
||
|
###### На третьем шаге wizjer 02.10.17 в 05:26 |
||
|
```acc = 1``` потому что это значение функция вернула на предыдущем шаге wizjer 02.10.17 в 05:27 |
||
|
```n = 2``` это третий элемент массива *number* wizjer 02.10.17 в 05:27 |
||
|
Функция возвращает *acc* + *n* --> 1 + 2 --> 3 wizjer 02.10.17 в 05:27 |
||
|
###### На четвертом шаге wizjer 02.10.17 в 05:28 |
