Что ж, поскольку статья прошлой недели имела такой успех (кстати, спасибо всем за лайки и ретвиты), я подумал, что должен продолжить с того места, где остановился!

Итак, в прошлый раз мы говорили о map, filter и reduce, о том, как они работают и как выглядят за кулисами.

На этот раз мы поговорим о составлении этих функций или их объединении в цепочку.

Опять же, мы посмотрим, как это выглядит с помощью наших самодельных функций, чтобы почувствовать это, а затем сделаем это с «настоящими» функциями JS.

Коротко и мило. Хороший. Давайте взломать.

У нас был массив:

let nums = [1,2,3,4,5,6,7,8,9];

Используя наши последние функции, мы будем отображать его, добавляя по одному к каждому, фильтровать его до чисел больше 5, а затем уменьшать то, что осталось, до суммы этих значений. Ожидается в общей сложности 40. Я думаю… (быстрые расчеты, понимаете).

Вот оно:

let ourMapResults = map(nums, addOne);
// [ 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
let ourFilterResults = filter(ourMapResults, moreThanFive);
// [ 6, 7, 8, 9, 10 ]
let ourReduceResults = reduce(0, ourFilterResults);
// 40

Ура, и правда, ХУЗЗА.

И, как и ожидалось, это прекрасно работает. Это довольно просто.

— Итак, что такое говядина? вы можете обнаружить, что спрашиваете (вы делаете, верно?).

Во-первых, вы создаете все эти новые переменные только для того, чтобы иметь возможность передать их следующей функции в цепочке. Они не будут использоваться снова, они не будут выполнять свою жизненную цель как переменные. Или что-то. Вы бы не хотели этого для своих переменных, не так ли?

Кроме того, каждый элемент в цепочке выполняет только одно действие. Легко следить за тем, что происходит.

Кроме того, это ОЧЕНЬ простой пример. Эти цепочки могут продолжаться очень долго и могут стать очень сложными. У вас будут дополнительные переменные повсюду, ваша кодовая база будет (вероятно) намного больше, менее ремонтопригодна и намного менее понятна.

Вероятно, есть много других причин, по которым он лучше, но посмотрите — сегодня воскресное утро. Прекрати меня придирать!

В любом случае - теперь давайте поступим "настоящим" способом:

let reduceResults = nums.map(addOne)
  .filter(n => n > 5)
  .reduce((sum, num) => sum + num, 0)
// 40

На что следует обратить внимание при этом:

let reduceResults = nums.map(addOne)
  .filter(n => n > 5)
  .reduce((sum, num) => sum + num, 0)

используются значения. Во-первых, это выглядит довольно странно:

let reduceResults = nums.map(addOne)

addOne ему ничего не передается. На самом деле это просто:

let reduceResults = nums.map(eachNumber => addOne(eachNumber))

map просматривает массив и передает каждое значение заданной функции (помните, что это всего лишь цикл for).

Каждая функция после нее берет результат предыдущей в цепочке и вводит его:

// n = nums.map(addOne)
.filter(n => n > 5)
/*
* It is worth noting here that the name of n can be anything. It is
* generally shortened as much as possible, but this is where it is
* made, you can call it what you want!
*/
.filter(numberOfMagicBeans => numberOfMagicBeans > 5)

Кстати, некоторые из вас могут быть знакомы с PHP и его конкатенацией точек (здесь я думаю о вас, Берт):

“this” . ” is” , “a” . “string”

Это может помочь думать о цепочке функций, чтобы они работали аналогичным образом:

"nums.map(addOne)" . "filter(n => n > 5)" . "reduce((sum, num) => sum + num, 0)"

Все, что вы на самом деле делаете с точкой, — это снова и снова обращаетесь к методам, хранящимся в объекте JS array prototype. Помните:

nums.map(addOne) 
// nums is an array (array.prototype.map)
thatNewArray.filter(n => n > 5) 
// (array.prototype.filter)
newerArray.reduce((sum, num) => sum + num, 0) 
// (array.prototype.reduce)

Кроме того, не позволяйте стрелочным функциям ES6 сбивать вас с толку.

Они облегчают чтение таких цепочек, но следите за тем, как они связываются с this, если у вас есть какой-либо объектно-ориентированный код.

На самом деле, все, что мы говорим, это то,

nums.filter(function (number) { 
    return number > 5;
}

filter может показаться немного сложным из-за всех знаков равенства и угловых скобок (особенно если мы проверяли >=, а не только >)!

Итак, поехали. Хорошие, красиво составленные функции.

Как и раньше, вы можете попробовать это в своем собственном терминале — скопируйте и вставьте, должно работать так же.

Если у вас есть какие-либо вопросы, напишите мне.

Может быть, будет больше (если я смогу придумать тему…).