数组迭代方法之reduce

昨天因为数据结构的封装上有点问题,就分别在开源中国和segmentFault上面提了问题,别问为什么不在stackoverflow里面提。。。

segmentFault里面的大神的答案果然不失所望。

其中有个答案是结合了reduce和map来编写的。map留着下次再说~请期待O(∩_∩)O~

所以今晚就看了一下关于reduce()的资料,才发现自己底子不行,之前理解的很多细节都没有注意到。翻回犀牛书认真读了一遍才茅塞顿开。

reduce()的参数

reduce()有两个参数,一个是回调函数(必选),另一个是传递给回调函数里prev参数的初始值(可选),这里的可选参数我就经常会把它忽略,导致产生理解误区

reduce()回调函数里面的参数

举个栗子:

var arr = [1,2,3,4];
var sum = arr.reduce(function(prev,cur,index,arr) {
    console.log(prev, cur, index);
    return prev + cur;
});
console.log(arr, sum);

/* console结果

1  2  1
3  3  2
6  4  3
[1,2,3,4] 10

*/
  • prev 函数第二项的值或是回调函数返回的累积值
  • cur 当前的迭代值
  • index 当前迭代值的索引
  • arr 数组本身

这里的prev很容易被误解,有很多人都会以为是数组里的cur的前一位数,其实一开始我也这么认为,console出来见真相啊。

前方高能,当第一次执行时,reduce方法里的没有第二个参数时,会默认把数组的第一位当成prev的值,上面的例子就是如此,所以第二位就成了cur值,所以index值是从1开始的。如果reduce的第二个参数设置了,则第一次执行,prev的值就是第二个参数。,如果要把prev设置为num型,第二个参数就为0,对象类型的话就设置为{},当然数组的就设置为[]

举些栗子:(栗子都是从前端三人行公众号上找的,比较懒。。。)

统计字符串有多少个相同字符


// 这里的reduce第二个参数是{},所以prev的初始值就是{}
var arrString = 'abcdaabc';  
arrString.split('').reduce(function(res, cur) {  
    res[cur] ? res[cur] ++ : res[cur] = 1  
    return res;  
}, {})

// 这里的reduce第二个参数是[],所以prev的初始值就是[]
[1, 2].reduce(function(res, cur) {   
    res.push(cur + 1);   
    return res;   
}, []);

reduce()和reduceRight()

reduce和reduceRight的原理其实是一样的,但是不同的是,它们是按照数组索引从高到低(从右到左)处理数组的。

下面例子就很适合用reduceRight()

var a = [2,3,4];

// 计算2^(3^4),乘方操作的优先顺序是从右到左
var big = a.reduceRight(function(accumulator,value) {
    return Math.pow(value, accumulator);
});

兼容问题

虽然reduce大法好用,但是在ie9以下的浏览器是不支持它的噢O__O “…

所以要请慎用!