JS数组reduce()方法详解及高级技巧

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}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值