文档里说reduce()
方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值。
reduce()
reduce() 函数接收2个参数(M: 必填, O: 可选):
(M) 回调reducer 函数 处理先前的结算结果和下一个元素直到序列结束。
(O) 初值 作为第一次调用回调时的第一个参数。
所以,让我们先看一个普通用法,之后再看一个复杂用法。
我们正在逛亚马逊(单价为美元$) 我们的购物车实在太满了,我们来计算一下总价吧:
// 当前的购物清单
var items = [{price: 10}, {price: 120}, {price: 1000}];
// reducer函数
var reducer = function add(sumSoFar, nextPrice) { return sumSoFar + nextPrice.price; };
// 开始运行
var total = items.reduce(reducer, 0);
console.log(total); // 1130
reduce
函数可选的参数在第一个例子里是基本变量数字0,但是它也可以是一个对象,数组… 而不仅是基本类型,之后我们将会看到。
现在,我们收到一个20$的优惠券。
var total = items.reduce(reducer,-20);
console.log(total); // 1110
第二种用法的例子是Redux
的combineReducers函数源码里用到的。
此创意是将reducer
函数拆分为独立的函数,最后组合成一个新的单一的大reducer
函数。
为了说明,我们创建一个单一的对象,包含一些可以计算不同货币($, €…)的总价值的reducer
函数。
var reducers = {
totalInDollar: function(state, item) {
state.dollars += item.price;
return state;
},
totalInEuros : function(state, item) {
state.euros += item.price * 0.897424392;
return state;
},
totalInPounds : function(state, item) {
state.pounds += item.price * 0.692688671;
return state;
},
totalInYen : function(state, item) {
state.yens += item.price * 113.852;
return state;
}
// more...
};
然后我们建立一个瑞士军刀函数
能够调用每一部分的reduce
函数
返回一个新的reducer
回调函数
var combineTotalPriceReducers = function(reducers) {
return function(state, item) {
return Object.keys(reducers).reduce(
function(nextState, key) {
reducers[key](state, item);
return state;
},
{}
);
}
};
现在,我们来看一下如何使用它。
var bigTotalPriceReducer = combineTotalPriceReducers(reducers);
var initialState = {dollars: 0, euros:0, yens: 0, pounds: 0};
var totals = items.reduce(bigTotalPriceReducer, initialState);
console.log(totals);
/*
Object {dollars: 1130, euros: 1015.11531904, yens: 127524.24, pounds: 785.81131152}
*/
我希望这种方法可以使你在自己的需求内使用reduce()
函数时有新的想法。
使用reduce
函数也可以实现保存每一次计算结果的功能。这在Ramdajs
里的scan函数已经实现了。
40 天前