2020-10-25 Array.reduce() 的用法

1、语法

array.reduce(callback,[initiaValue]);

reduce 为数组中的每一个元素执行回调函数,不包括未被赋值的元素。
回调函数中有四个参数

2、回调函数参数

  • previousValue : 上一次调用返回的值,因为第一次没有返回值,所以第一次默认返回1
  • currentValue : 当前值,默认从数组下标为 1 的开始
  • currentIndex : 当前索引,默认从数组下标为 1 的开始
  • array : 当前数组
var arr = [1,2,3,4,5];
arr.reduce(function(previousValue,currentValue,currentIndex,array){
	console.log(previousValue,currentValue,currentIndex,array);
	//1 2 1 (5) [1, 2, 3, 4, 5]
 	//undefined 3 2 (5) [1, 2, 3, 4, 5]
	//undefined 4 3 (5) [1, 2, 3, 4, 5]
	//undefined 5 4 (5) [1, 2, 3, 4, 5]
})

上面的结果可以看到,currentValue 和 currentIndex 的值确实是从索引为 1 开始打印的,可是为什么 previousValue 的值除了第一次打印 1 ,其余全是 undefined
这里就是展现 reduce 作用的一部分,上面参数中说明了 previousValue 的值是上一次回调函数的返回值,上面的例子中没有返回值,那我们给他一个返回值

	var arr = [1,2,3,4,5];
    arr.reduce(function (previousValue,currentValue,currentIndex,array) {
        console.log(previousValue,currentValue,currentIndex,array);
        return previousValue + currentValue;
        //1 2 1 (5) [1, 2, 3, 4, 5]
 		//3 3 2 (5) [1, 2, 3, 4, 5]
 		//6 4 3 (5) [1, 2, 3, 4, 5]
 		//10 5 4 (5) [1, 2, 3, 4, 5]
    })

可以看到,previousVaule 确实打印了上一次的返回值,可是 reduce() 中每次从下标为 1 开始取值,还不如 for 循环适用,如何解决下标问题呢?

reduce() initialValue 参数

reduce() 除了callback 回调函数这个参数之外,还有一个 initiaValue 参数,这个参数是初始值的意思

  • 初始值可以为任意值,相当于给 previousValue 赋值
  • 当我们往 initiaValue 形参传值的时候, currentValue 和 currentIndex 的初始值不再是索引为 1 的值,而是 从索引为 0 开始找**(注意:传递任意值都会让初始值改变,只有 previousValue 来接收这个参)**
	var arr = [1,2,3,4,5];
    arr.reduce(function (previousValue,currentValue,currentIndex,array) {
        console.log(previousValue,currentValue,currentIndex,array);
        return previousValue + currentValue;
        //0 1 0 (5) [1, 2, 3, 4, 5]
		//1 2 1 (5) [1, 2, 3, 4, 5]
		//3 3 2 (5) [1, 2, 3, 4, 5]
		//6 4 3 (5) [1, 2, 3, 4, 5]
		//10 5 4 (5) [1, 2, 3, 4, 5]
    },0);//这里传了一个 0 作为参数,相当于 previousValue = 0;

如果我们传递一个空数组会得到什么结果?

	var arr = [1,2,3,4,5];
    var newArr = arr.reduce(function (previousValue,currentValue,currentIndex,array) {//因为最后一次调用的结果会返回出来,我们接受打印一下
        console.log(previousValue,currentValue,currentIndex,array);
        return previousValue + currentValue;
		// [] 1 0 (5) [1, 2, 3, 4, 5]
    	// 1 2 1 (5) [1, 2, 3, 4, 5]
    	// 12 3 2 (5) [1, 2, 3, 4, 5]
    	// 123 4 3 (5) [1, 2, 3, 4, 5]
    	// 1234 5 4 (5) [1, 2, 3, 4, 5]
     },[]);//这里传递了一个空数组
     console.log(newArr);//123454

当我们传递空数组的时候,currentValue 和 currentIndex 都是从索引为 0 开始的,previousValue = []; 得到的结果不再是相加的值,而是字符串拼接**(注意:传递空数组,得到的是字符串拼接,并不是想象中的数组拼接)**

reduce() 常用技巧

  1. 数组求和、求积
var arr = [1,2,3,4,5];
//求和
var sum = arr.reduce(function(prev , value , index ){
	return prev + value;//因为 prev 是每一次回调的值,所以这一句就相当于 prev = prev + value
},0);
console.log(sum);

//求积
var product = arr.reduce(function(prev , value , index){
	return prev*value;//prev = prev*value
},1);//因为是求积,所以 prev 的初始值为 1
console.log(product);
  1. 数组中每个元素(或字母)出现的次数
    因为 reduce 是数组的方法,字符串使用得先转换成数组
var arr = 'abbdfghdfg';
arr = arr.split('');//因为 reduce 是数组的方法,所以得先转换成数组
var obj = arr.reduce(function(prev , value , index){
	if(value in prev){
		prev[value]++;
	}else{
		prev[value] = 1;
	}
	return prev;
},{});//需要用对象的值去保存每个字母出现的次数,所以初始值为空对象
console.log(obj);//{a: 1, b: 2, d: 2, f: 2, g: 2, h:1}
  1. 数组去重
var arr = [1,2,4,4,5];
var newArr = arr.reduce(function(prev , value , index){
    if(prev.indexOf(value) == -1){
         prev.push(value);
     }
     return prev;
 },[]);
 console.log(newArr);//[1,2,4,5]因为通过 push() 方法添加的,所以返回的是数组
  1. 二维数组转为一维数组
    这种方法只适用于数组元素全为数组
var arr = [[1,2],[3,4],[5,6]];
var newArr = arr.reduce(function(prev,value,index){
	return prev.concat(value);
},[]);
console.log(newArr);//[1,2,3,4,5,6]
  1. 多维数组拍平
var arr = [1,[2,3],[4,[5,6]]];
function oneDimensional(arr){
	return arr.reduce(function(prev,value,index){
		return prev.concat(Array.isArray(value) ? oneDimensional(value) : value);
		//用 prev 空数组去拼接每一个当前值,如果当前值为数组,就调用拍平函数,如果不是数组,就直接拼接
	},[]);
}
var newArr = oneDimensional(arr);
console.log(newArr);//[1,2,3,4,5,6]

  1. 对象里的属性求和
var arr = [{
	subject:'math',
	score:50
},
{
	subject:'chinese',
	score:60
},
{
	subject:'english',
	score:55
}];

var sum = arr.reduce(function(prev,value,index){
	return prev + value.score;
},0);
console.log(sum);//165
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值