Reduce - Part 3 of 函数式编程
-
虽然reduce, map, filter常常被放在一起介绍,但是reduce的用法比较特殊,也比较难掌握,虽然在函数式编程的第一章,我们介绍过reduce,但是我还是觉得有必要在这里更加深入的介绍一下。
基本上我可以用下面表达式来描述reduce
const arr=[1,2,3]; function f (a, b) { return a + b; } arr.reduce (f) = f(f(arr[0], arr[1]), arr[2]);
分解开来,就是:
const result = f(arr[0], arr[1]) = f(1, 2) = 3; result = f(result, arr[2]) = f(3,3) = 6;
其实reduce还有第二个参数,也就是所谓的初始值,如果我们定义了这个值,那么,第一次传入给处理函数的参数就是不是数组的前两个成员,而是,这个初始值和数组的第一个成员。表达式如下:
arr.reduce(f, INIT) = f(f(f(INIT, arr[0]), arr[1]), arr[2]);
如果数组成员不是简单的数值或者字符串,那是这个初始值就变得很有用。
看下面这个数组:
const orders =[ {amount: 1}, {amount: 2}, {amount: 3}, {amount: 4} ]
如果你用上面的reduce来计算总和就行不通了:
const total = orders.reduce((x,y)=>x.amount + y.amount);
虽然第一次调用求和函数,等到结果 = orders[0].amount + orders[1].amount = 3, 但是第二次我们把3 和 orders[2] 传给求和函数,我们就无法得到正确结果,因为3.amount是不存在的。
解决这个问题,我们需要用到初始值,如下:const result2 = arr.reduce( (x,y) => { return x + y.amount; }, 1 );