1 定义和用法
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
reduce() 可以作为一个高阶函数,用于函数的 compose。
注意: reduce() 对于空数组是不会执行回调函数的。
2 语法
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
3 参数
reduce()方法接收两个参数,第一个是一个callback函数(必选),第二个是初始值(可选)。
参数 | 描述 |
---|---|
function(total,currentValue, index,arr) | 必需。用于执行每个数组元素的函数。 |
initialValue | 可选。传递给函数的初始值 |
其中,callback函数参数如下:
参数 | 描述 |
---|---|
total | 必需。初始值, 或者计算结束后的返回值。 |
currentValue | 必需。当前元素 |
currentIndex | 可选。当前元素的索引 |
arr | 可选。当前元素所属的数组对象。 |
4 应用
(1)四舍五入后计算数组元素的总和:
var numbers = [15.5, 2.3, 1.1, 4.7];
function getSum(total, num,currentIndex) {
console.log(currentIndex);
return total + Math.round(num);
}
numbers.reduce(getSum); //输出1, 2, 3, 23.5
numbers.reduce(getSum,0); //输出0, 1, 2, 3, 24
可以发现,当使用reduce方法只传一个回调函数,而没有传初始值的情况下,回调函数中会将目标数组的第一个元素作为该回调函数的初始值(第一个参数),然后从数组第二个元素开始进行遍历并执行回调函数中的操作,最后得到一个返回值;在传递初始值的情况下,回调函数会将reduce()函数接收到的初始值作为初始值,并从目标数组的第一个元素开始遍历。
reduce函数的返回结果类型和传入的初始值相同,上个实例中初始值为number类型,同理,初始值也可为object类型。还是上面的例子:
var numbers = [15.5, 2.3, 1.1, 4.7];
function getSum(total, num,currentIndex) {
console.log(currentIndex);
total.sum += Math.round(num);
return total
}
numbers.reduce(getSum, {sum:0}); //输出0, 1, 2, 3, {sum:24}
举个实际点的栗子:
小明期末考试成绩如下:
var scores =[
{
subject:"chinese",
score:95
},
{
subject:"english",
score:75
},
{
subject:"math",
score:81
}
]
假如Chinese、English和math三门学科的比重分别是40%,30%,30%,求小明的加权成绩和。
var dis = {
chinese:0.4,
english:0.3,
math:0.3
};
function getSum(sum, subjectItem) {
sum+= subjectItem.score * dis[subjectItem.subject];
return sum;
}
scores.reduce(getSum, 0); // 输出84.8
(2)计算字符串中每个字母出现的次数?
var str = 'abcdaabc';
str.split('').reduce(function(res, cur) {
res[cur] ? res[cur] ++ : res[cur] = 1
return res;
}, {}) // 输出{a: 3, b: 2, c: 2, d: 1}
还可以这么写:
var str = 'abcdaabc';
var tempArr = [];
var tempObj = {};
str.split('').forEach(function(item){
if(tempArr .indexOf(item) > -1){
tempObj[item] = tempObj[item]+1;
}else{
tempArr.push(item)
tempObj[item] = 1;
}
}) // 输出{a: 3, b: 2, c: 2, d: 1}
(3)扩展应用
由于可以通过第二参数设置叠加结果的类型初始值,因此这个时候reduce就不再仅仅只是做一个加法了,我们可以灵活的运用它来进行各种各样的类型转换,比如将数组按照一定规则转换为对象,也可以将一种形式的数组转换为另一种形式的数组,大家可以动手去尝试一样。就比如上面的统计字符串中各个字母出现的次数,其实就是讲数组转换成了对象形式。
下面是数组转换还是数组形式:
[1, 2].reduce(function(res, cur) {
res.push(cur + 1);
return res;
}, [])
koa的源码中,有一个only模块,整个模块就一个简单的返回reduce方法操作的对象:
var only = function(obj, keys){
obj = obj || {};
if ('string' == typeof keys) keys = keys.split(/ +/);
return keys.reduce(function(ret, key){
if (null == obj[key]) return ret;
ret[key] = obj[key];
return ret;
}, {});
};
通过对reduce概念的理解,这个模块主要是想新建并返回一个obj对象中存在的keys的object对象。
var a = {
env : 'development',
proxy : false,
subdomainOffset : 2
}
only(a,['env','proxy']) // {env:'development',proxy : false}