前言
在日常项目过程中,需要进行数组对象的去重,度娘后发现有大佬用reduce去重惊为天人,故来学习一下
语法
arr.reduce(callback, [initialValue])
MDN中定义:reduce方法为数组里的每个元素执行callback函数,不包括数组中被删除或从未被赋值的元素
返回值
返回值是回调函数return内容
参数
其中函数callback接受四个参数:
-
accumulator:累计器累计回调的返回值,它是上一次调用回调时返回的累积值,或者initialValue(详见initialValue)
-
currentValue:数组中正在处理的元素
-
currentIndex:该参数为可选的,数组中正在处理的元素的索引,如果提供了initialValue则索引值从0开始,否则从1开始
-
array:该参数为可选的,调用reduce()的数组
再来说一下initialValue参数
定义:
该参数是可选可不选的,但是填与不填的区别很大,如果它提供了初始值,则作为callback函数的第一个参数(accumulator)的值,如果没有初始值,则使用数组的第一个元素作为callback的初始值。
注意:如果提供了initialValue则索引值从0开始,否则从1开始。
分别举两个例子来说明不同的情况:
1.initialValue不存在时
/** 当initialValue参数不存在 **/ let arr = [0,1,2,3]; let arrresult = arr.reduce((accumulator,currentValue,currentIndex)=>{ console.log(`累加器:${accumulator}`,`当前处理的元素:${currentValue}`,`当前索引:${currentIndex}`) return accumulator+currentValue }) console.log(arrresult)
输出的值为
累加器:0 当前处理的元素:1 当前索引:1 累加器:1 当前处理的元素:2 当前索引:2 累加器:3 当前处理的元素:3 当前索引:3 6
2.initialValue存在时
/** 当initialValue参数存在 **/ let arr = [0, 1, 2, 3]; let arrresult = arr.reduce((accumulator, currentValue, currentIndex) => { console.log(`累加器:${accumulator}`, `当前处理的元素:${currentValue}`, `当前索引:${currentIndex}`) return accumulator + currentValue },7) console.log(arrresult)
输出的值为
累加器:7 当前处理的元素:0 当前索引:0 累加器:7 当前处理的元素:1 当前索引:1 累加器:8 当前处理的元素:2 当前索引:2 累加器:10 当前处理的元素:3 当前索引:3 13
总结:当initialValue参数存在时,它就可以作为callback的第一个参数的初始值,并且遍历的次数从索引0开始,当initialValue参数不存在时,以数组的第一个元素作为callback第一个参数的初始值,并且遍历的索引从1开始
注意:通常来说,给initialValue设置个初始值是最安全的,当参与reduce的数组时空的话会报错,因为拿不到数组的第一个元素作为callback函数的起始值,但是设置了initialValue的初始值就可以避免这个问题
//数组为空,没有设置initialValue的初始值 let arr = []; let arrresult = arr.reduce((accumulator, currentValue, currentIndex) => { console.log(`累加器:${accumulator}`, `当前处理的元素:${currentValue}`, `当前索引:${currentIndex}`) return accumulator + currentValue }) console.log(arrresult) //报错 //打印错误信息reduce.html:31 Uncaught TypeError: Reduce of empty array with no initial value //数组为空,设置了initialValue的初始值 let arr1 = []; let arrresult1 = arr1.reduce((accumulator, currentValue, currentIndex) => { console.log(`累加器:${accumulator}`, `当前处理的元素:${currentValue}`, `当前索引:${currentIndex}`) return accumulator + currentValue }) console.log(arrresult1) //不报错 //打印7
reduce的应用场景
那reduce有什么用呢,那么多遍历方法我为什么要选择reduce,我暂时还不大知道,可能是为了高大上,更酷吧,我们来看几个应用场景
1.累和/累积
let arr = [1,2,3,4]; let arrresult = arr.reduce((accumulator, currentValue, currentIndex) => { return accumulator+currentValue },0) console.log(arrresult) //10
2.求最大值/最小值
let arr = [200,2,3,4,100]; let arrresult = arr.reduce((accumulator, currentValue, currentIndex) => { return Math.max(accumulator, currentValue) }) console.log(arrresult) //200 let arrresult1 = arr.reduce((accumulator, currentValue, currentIndex) => { return Math.min(accumulator, currentValue) }) console.log(arrresult1) //2
3.数组对象去重
//数组对象去重 function duplicate(arrayobj, key) { //采用一个第三方的对象来判断 let obj = {} return arrayobj.reduce((accumulator, currentValue, currentIndex) => { //当前key键的value值存在于obj函数中时,说明重复 if (!obj[currentValue[key]]) { obj[currentValue[key]] = true accumulator.push(currentValue) } return accumulator }, []) } console.log(duplicate(array, 'id'))