1.语法
arr.reduce(callbackFn, [initialValue])
reduce() 方法会对数组中的每个元素按顺序执行你提供的回调函数。
callbackFn 回调函数中,可以接受四个参数:
previousValue:上一次调用callbackFn时的返回值。在第一次调用时,并没有执行过回调函数,所以没有返回值,如果你指定了初始值initialValue,那么这个值就会作为第一次调用时的返回值;否则的话就会把数组的第一项arr[0]当作第一次调用时的返回值。currentValue:数组中正在处理的元素。currentIndex:currentValue的索引值。array:用于遍历的数组。
2.[initialValue]传与不传的区别
首先来看不传:
const arr = [1, 2, 3, 4]
const sumWithoutInitial = arr.reduce((pre, cur, index, arr) => {
console.log(pre, cur, index, arr)
return pre + cur
})
console.log(sumWithoutInitial)
// 打印结果
1 2 1 [1, 2, 3, 4]
3 3 2 [1, 2, 3, 4]
6 4 3 [1, 2, 3, 4]
10
从打印结果我们可以看出来,index 是从 索引1 开始的,arr[0] 被当作了第一次调用时 pre 的值。
再来看传:
const arr = [1, 2, 3, 4]
const initialValue = 0
const sumWithInitial = arr.reduce((pre, cur, index, arr) => {
console.log(pre, cur, index, arr)
return pre + cur
}, initialValue)
console.log(sumWithInitial)
// 打印结果
0 1 0 [1, 2, 3, 4]
1 2 1 [1, 2, 3, 4]
3 3 2 [1, 2, 3, 4]
6 4 3 [1, 2, 3, 4]
10
这次 index 是从 索引0 开始的, 第一次调用时 pre 的值是 initialValue。
所以,作为第一次调用 callback 函数时,若指定了初始值 initialValue,则 currentValue 则将使用数组第一个元素;否则 previousValue 将使用数组第一个元素,而 currentValue 将使用数组第二个元素。
3.常见用法
(1)计算数组中各元素出现的次数
const items = [3, 2, 2, 8, 1, 5, 8]
const itemNum = items.reduce((pre, cur) => {
if (pre[cur]) {
pre[cur]++
} else {
pre[cur] = 1
}
return pre
}, {})
console.log(itemNum)
// {1: 1, 2: 2, 3: 1, 5: 1, 8: 2}
// 也可以简写:
const itemNum = items.reduce((pre, cur) => (pre[cur]++ || (pre[cur] = 1), pre), {})
(2)求数组所有值的和
const sum = [0, 1, 2, 3].reduce((pre, cur) => pre + cur, 0)
console.log(sum) // 6
(3)累加对象数组里的值
const sum = [{x: 1}, {x: 2}, {x: 3}].reduce((pre, cur) => pre + cur.x, 0)
console.log(sum) // logs 6
(4)将二维数组转为一维
const flattened = [[0, 1], [2, 3], [4, 5]].reduce((pre, cur) => pre.concat(cur), [])
console.log(flattened) // [0, 1, 2, 3, 4, 5]
(5)数组去重
const myArray = ['a', 'b', 'a', 'b', 'c', 'e', 'e', 'c', 'd', 'd', 'd', 'd']
const myArrayWithNoDuplicates = myArray.reduce((pre, cur) => {
if (pre.indexOf(cur) === -1) {
pre.push(cur)
}
return pre
}, [])
console.log(myArrayWithNoDuplicates) // ['a', 'b', 'c', 'e', 'd']