浅析reduce与reduceRight

  在传统的实际开发中,经常在遇到处理数组的一些问题的时候就采用for循环,当然可以解决遇到的问题,但是站在优雅的角度来看是相当不优雅的,况且是在现在其实是有现成的api能够更好的解决for循环能够解决的问题,下面简单介绍下数组的这两个方法,reducereduceRight.

reduce

定义

对数组中的所有元素调用指定的回调函数。该回调函数的返回值为累积结果,并且此返回值在下一次调用该回调函数时作为参数提供。

语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
array1.reduce(callbackfn[, initialValue])

参数
- array1 必需,一个数组对象
- callbackfn 必需。一个接受最多四个参数的函数。对于数组中的每个元素,reduce 方法都会调用 callbackfn 函数一次。
- initialValue 可选。如果指定 initialValue,则它将用作初始值来启动累积。第一次调用 callbackfn 函数会将此值作为参数而非数组值提供。

返回值

- 通过最后一次调用回调函数获得的累积结果。

异常
当满足下列任一条件时,将引发 TypeError 异常:
- callbackfn 参数不是函数对象。
- 数组不包含元素,且未提供 initialValue。

注意点

  • 如果提供了 initialValue,则 reduce 方法会对数组中的每个元素调用一次 callbackfn 函数(按升序索引顺序)。如果未提供 initialValue,则 reduce 方法会对从第二个元素开始的每个元素调用 callbackfn 函数。

  • 回调函数的返回值在下一次调用回调函数时作为 previousValue 参数提供。最后一次调用回调函数获得的返回值为 reduce 方法的返回值。

  • 不为数组中缺少的元素调用该回调函数。

回调函数语法

1
2
3
4
5
6
7
8
9
回调函数的语法如下所示:

function callbackfn(previousValue, currentValue, currentIndex, array1)

可使用最多四个参数来声明回调函数。
- previousValue 通过上一次调用回调函数获得的值。如果向 `reduce` 方法提供 initialValue,则在首次调用函数时,previousValue 为 initialValue。
- currentValue 当前数组元素的值。
- currentIndex 当前数组元素的数字索引。
- array1 包含该元素的数组对象。

第一次调用回调函数

在第一次调用回调函数时,作为参数提供的值取决于 reduce 方法是否具有 initialValue 参数。

如果向 reduce 方法提供 initialValue:

  • previousValue 参数为 initialValue。

  • currentValue 参数是数组中的第一个元素的值。

如果未提供 initialValue:

  • previousValue 参数是数组中的第一个元素的值。

  • currentValue 参数是数组中的第二个元素的值。

实际应用

例子1 数组求和问题

传统for循环方式
1
2
3
4
5
6
const arr = [3,4,5,6];
let sum = 0;
for(let i = 0, len = arr.length; i < len; i++) {
sum += arr[i];
}
console.log('sum', sum);
reduce方式
1
2
3
4
5
6
const arr = [3,4,5,6];
function sumFunc(prev, curr) {
return prev += curr;
}
let sum = arr.reduce(sumFunc, 0);
console.log('sum', sum);

例子2 数组去重问题

传统for循环方式
1
2
3
4
5
6
7
8
9
10
11
12
13
const arr = [3,4,5,6,6,3];
function removeDuplicate(array) {
const newArr = [];
const obj = {};
for(let i = 0, len = array.length; i < len; i++) {
if(!obj[array[i]]) {
newArr.push(array[i]);
obj[array[i]] = 1;
}
}
return newArr;
}
console.log('arr', removeDuplicate(arr));
reduce方式
1
2
3
4
5
6
7
8
9
10
11
12
const arr = [3,4,5,6,6,3];
function removeDuplicate(array) {
const obj = {};
return array.reduce((prev, next) => {
if(!obj[next]) {
prev.push(next);
obj[next] = 1;
}
return prev;
}, []);
}
console.log('arr', removeDuplicate(arr));

reduceRight

定义

降序顺序对数组中的所有元素调用指定的回调函数。该回调函数的返回值为累积结果,并且此返回值在下一次调用该回调函数时作为参数提供,其实主要就是调用回调函数的时候是从右边开始调用,其他的跟reduce并无多大区别,这里就不详细介绍了

结语

上面只是举了两个比较常见的例子,数组求和和数组去重,其实reduce的用法是相当强大的,redux框架里就用到了reduce,在这里记录下来也是提醒自己以后不要把思维固化到以前的观念上,要多去关注和尝试一些新的特性,不断去尝试用更优雅的方式去解决问题。