reduce函数探索

看标题估计很多人都懵了,一个ES内置的函数reduce有什么好讲的.非也非也,请看下去!

reduce的定义

reduce对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总然后返回。

reduce的语法

arr.reduce(callback,initialValue)

callback函数:

  • accumulator 累计器累计回调的返回值
  • currentValue 当前元素
  • currentIndex 当前元素的索引 (可选)
  • arr 当前数组 (可选)

initialValue

作为第一次调用 callback函数时的第一个参数的值 (可选)

tips:如果你不写initialValuecallback函数的第一次调用从数组索引1开始,如果提供initialValue,从索引0开始

很多人喜欢这样写

arr.reduce(function(prev,next){},initialValue)

这样也没有错,但是很容易让人理解为类似于for循环,不就前一个后一个嘛然后循环,其实这里的prev是前一轮调用回调时返回的累积值,或initialValue

建议写法:

arr.reduce((acc,cur,index,arr)=>{},initialValue)

reduce函数如何运行

[0, 1, 2, 3, 4].reduce((acc, cur, index, arr)=>{
  return acc + cur;
});

按照上面的说明,不提供initialValue,那么callback,将从索引1开始,所以callback将会调用四次

callback acc cur index arr return
1 0 1 1 [0,1,2,3,4] 1
2 1 2 2 [0,1,2,3,4] 3
3 3 3 3 [0,1,2,3,4] 6
5 6 4 4 [0,1,2,3,4] 10

从上面的表格我们可以非常直观的看到callback是如何一步一步把一个数组求和的

函数式编程中的reduce

函数式编程属于js高阶技巧吧,主要依靠那几个ES提供的函数来实现。
阮一峰老师的函数式编程入门

案例(多维数组降维)

let flateen=(arr)=>{
    return arr.reduce((acc,cur)=>{
        return acc.concat(Array.isArray(cur)?flateen(cur):cur)
    },[])
}

意思是从索取0开始,判断当前元素是否是数组,如果是,那么进行递归,如果不是就返回当前数组,然后和前一轮的返回值(一个一纬数组)进行拼接

reduceRight

reduce是一样的,只不过reduce是从左到右遍历,而reduceRight是从右到左遍历,其他什么,语法啊,用法都一样。

arr.reduceRight((acc, cur, index, arr) =>{
    // ...
},initialValue);

稍微有点不同的是,如果没有提供initialValue参数,则 acc等于数组最后一个值, cur等于数组中倒数第二个值,因为是从右到左嘛。

与reduce之间的区别(案例)

var a = ['1', '2', '3', '4', '5']; 
var left  = a.reduce((acc, cur) =>{ return acc + cur; }); 
var right = a.reduceRight((acc, cur) => { return acc + cur; }); 
console.log(left);  // "12345"
console.log(right); // "54321"