前言
在日常项目过程中,需要进行数组对象的去重,度娘后发现有大佬用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.数组对象去重
let array = [
{id:1,name:"掘金"},
{id:2,name:"JKL"},
{id:3,name:"JKD"},
{id:5,name:"JKX"},
{id:1,name:"掘金是掘金"}
]
//数组对象去重
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'))