有人可以向我解释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
所以,根据我对reduce函数的了解(这还不够),Array.reduce通过这样的数组进行迭代-它获取每个数组值,并将它们与另一个参数一起通过回调函数放入(称为累加器) 。下一个数组值将使用相同的回调函数,但是(最终)累加器值会更改。
在上面的代码示例中使我感到困惑的是:
1)数组是功能列表[double,add5]。
2]在第一次迭代中,composeB将接收参数:f =累加器(空值),g = double(函数)。 ComposeB应该返回emptyvalue(double(6))(或者可能不是吗?)
我知道我缺少什么,但是有人可以向我解释什么吗?
reduce的文档说第一个参数是
在数组中的每个元素上执行的函数(如果没有提供initialValue,则第一个元素除外)。
因此,在这种情况下,您没有提供initialValue
,因此compose
仅被调用一次(带有参数double
和add5
)。
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
的默认值(第二个参数)f1
时,这些函数才会被执行。[a,b,c,d,e]
中的所有功能放入e,d,c,b,a
的链中(反向顺序!),然后以e(d(c(b(a(10)))))
的形式执行以获取我们想要的顺序。(f,g) => (_) => g(f(_))
function compose (f, g) { return function (z) { return g(f(z)); }; }
p.s .:我使用var
,因为我可以;)
顺便说一句,您需要使用reduceRight
,因为如果在数组中添加另一个函数,则顺序错误。
const
composeB = (f, g) => x => f(g(x)),
add = a => b => a + b,
add5 = add(5),
double = a => a * 2,
three = a => a * 3,
add5ThenDouble = [double, add5, three].reduceRight(composeB);
console.log(add5ThenDouble(6)); // 51