Как Array.reduce ставит функции как параметры в композиции функций? - PullRequest
0 голосов
/ 08 января 2020

Может кто-нибудь объяснить мне, как Array.reduce может поместить функции в качестве аргументов в состав функции следующим образом:

const  composeB  = (f, g) =>  x  =>  f(g(x))

const  add = a => b => a  +  b
const  add5 = add(5)
const  double = a => a * 2

const add5ThenDouble  = [double, add5].reduce(composeB)

console.log(add5ThenDouble(6)); // 22

Итак, насколько мне известно (этого недостаточно), функция редуктора состоит в том, что Array .reduce перебирает массив таким образом - он берет каждое из значений массива и помещает их через функцию обратного вызова с другим аргументом (давайте назовем его аккумулятором). Следующее значение массива будет под go той же функцией обратного вызова, но с (в конечном итоге) измененным значением аккумулятора.

Что меня смущает в приведенном выше примере кода:

1) Массив - это список functions [double, add5].

2) На первой итерации composeB получит аргументы: f = аккумулятор (пустое значение), g = double (функция). ComposeB должен вернуть emptyvalue (double (6)) (или, может быть, нет ??)

Я знаю, что что-то упустил, но может кто-нибудь объяснить мне, что?

Ответы [ 2 ]

1 голос
/ 08 января 2020

В документации на lower указано, что первый аргумент -

Функция, выполняемая для каждого элемента в массиве (кроме первого, если не указано значение initialValue).

Таким образом, в этом случае вы не указали initialValue, и поэтому compose вызывается только один раз (с аргументами double и add5).

0 голосов
/ 08 января 2020
var inc = (x) => ++x, // increment +1
    x2 = (x) => x*2, // multiply by 2
    sq = (x) => x*x; // square

var compose = (f,g) => (_) => g(f(_));

var f1 = [ sq, inc, inc ].reduce(compose, (_) => _); 
f1(10); // 102

var f2 = [ inc, sq, inc ].reduce(compose, (_) => _); 
f2(10); // 122

См. Код выше, обратите внимание:

  • функция идентификации (_) => _ в качестве значения по умолчанию (второй аргумент) для reduce
  • compose НЕ вернет число , он вернет ФУНКЦИЮ, которая является композицией всех функций, которые были переданы ранее ... Так что - только когда вы ВЫЗЫВАЕТЕ (скажем) f1, только тогда функции будут выполняться.
  • мы помещаем все функции из списка [a,b,c,d,e] в цепочку e,d,c,b,a (в обратном порядке!) и затем выполняем как e(d(c(b(a(10))))), получая заказ, который мы на самом деле хотели.
  • (f,g) => (_) => g(f(_)) <- function аргументы фактически меняются при их вызове. Более длинная версия: <code>function compose (f, g) { return function (z) { return g(f(z)); }; }

пс: я использую var, потому что могу;)

...