reduce详解与实战

reduce() 方法对数组中的每个元素执行一个提供的 reducer 函数(升序执行),将其结果汇总为单个返回值。传递给 reduce 的回调函数(callback)接受四个参数,分别是累加器 accumulator、currentValue——正在操作的元素、currentIndex(可选)——元素索引,但是它的开始会有特殊说明、array(可选)——原始数组本身,除了 callback 之外还可以接受初始值 initialValue 值(可选)。

  1. 如果没有提供 initialValue,那么第一次调用 callback 函数时,accumulator 使用原数组中的第一个元素,currentValue 即是数组中的第二个元素。在没有初始值的空数组上调用 reduce 将报错。

  2. 如果提供了 initialValue,那么将作为第一次调用 callback 函数时的第一个参数的值,即 accumulator,currentValue 使用原数组中的第一个元素。

例子,现在有一个数组 [0, 1, 2, 3, 4],需要计算数组元素的和,需求比较简单,来看下代码实现。

不使用高阶函数

1
2
3
4
5
6
7
8
9
10
const arr = [0, 1, 2, 3, 4];
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i];
}

console.log( sum );
// 10
console.log( arr );
// [0, 1, 2, 3, 4]

使用高阶函数
无 initialValue 值

1
2
3
4
5
6
7
8
9
const arr = [0, 1, 2, 3, 4];
let sum = arr.reduce((accumulator, currentValue, currentIndex, array) => {
return accumulator + currentValue;
});

console.log( sum );
// 10
console.log( arr );
// [0, 1, 2, 3, 4]

上面是没有 initialValue 的情况,代码的执行过程如下,callback 总共调用四次。

callback accumulator currentValue currentIndex array return value
first call 0 1 1 [0, 1, 2, 3, 4] 1
second call 1 2 2 [0, 1, 2, 3, 4] 3
third call 3 3 3 [0, 1, 2, 3, 4] 6
fourth call 6 4 4 [0, 1, 2, 3, 4] 10

有 initialValue 值

我们再来看下有 initialValue 的情况,假设 initialValue 值为 10,我们看下代码。

1
2
3
4
5
6
7
8
9
const arr = [0, 1, 2, 3, 4];
let sum = arr.reduce((accumulator, currentValue, currentIndex, array) => {
return accumulator + currentValue;
}, 10);

console.log( sum );
// 20
console.log( arr );
// [0, 1, 2, 3, 4]

代码的执行过程如下所示,callback 总共调用五次。

callback accumulator currentValue currentIndex array return value
first call 10 0 0 [0, 1, 2, 3, 4] 10
second call 10 1 1 [0, 1, 2, 3, 4] 11
third call 11 2 2 [0, 1, 2, 3, 4] 13
fourth call 13 3 3 [0, 1, 2, 3, 4] 16
fifth call 16 4 4 [0, 1, 2, 3, 4] 20