reduce的妙用

计算数组的总和

const arr = [1, 2, 3, 4, 5]
const result = arr.reduce((accumulator, currentValue) => accumulator += currentValue)
console.log(result) // 15

计算数组的平均数

const arr = [1, 2, 3, 4, 5]
const result = arr.reduce((accumulator, currentValue, currentIndex, array) => {
accumulator += currentValue
if (currentIndex === array.length - 1) {
return accumulator / array.length
}
return accumulator
})
console.log(result) // 3

求数组的最大值

const arr = [1, 2, 3, 4, 5]
const result = arr.reduce((previousValue, currentValue) => Math.max(previousValue, currentValue))
console.log(result) // 5

求数组的最小值

const arr = [1, 2, 3, 4, 5]
const result = arr.reduce((previousValue, currentValue) => Math.min(previousValue, currentValue))
console.log(result) // 1

数值去重

const arr = [1, 2, 3, 4, 5, 5, 6, 3, 4, 1, 19]
const result = arr.reduce((accumulator, currentValue) => {
if (!accumulator.includes(currentValue)) {
accumulator.push(currentValue)
}
return accumulator
}, [])
console.log(result) // [1, 2, 3, 4, 5, 6, 19]

计算数组中每个元素出现的次数

const arr = [1, 2, 3, 4, 5, 5, 6, 3, 4, 1, 19]
const result = arr.reduce((accumulator, currentValue) => {
if (!accumulator[currentValue]) {
accumulator[currentValue] = 1
} else {
accumulator[currentValue]++
}
return accumulator
}, {})
console.log(result) // {1: 2, 2: 1, 3: 2, 4: 2, 5: 2, 6: 1, 19: 1}

实现数组分组

const arr = [1, 2, 3, 4, 5, 5, 6, 3, 4, 1, 19]
const result = arr.reduce((accumulator, currentValue) => {
if (currentValue % 2 === 0) {
accumulator.even.push(currentValue)
} else {
accumulator.odd.push(currentValue)
}
return accumulator
}, { even: [], odd: [] })
console.log(result)
/*
even: (4) [2, 4, 6, 4]
odd: (7) [1, 3, 5, 5, 3, 1, 19]
*/

计算数组中连续递增数字的长度

const arr = [1, 2, 3, 4, 5, 5, 6, 3, 4, 1, 19]
const result = arr.reduce((accumulator, currentValue, currentIndex, array) => {
if (currentIndex === 0 || currentValue !== array[currentIndex - 1] + 1) {
accumulator.push([currentValue])
} else {
accumulator[accumulator.length - 1].push(currentValue)
}
return accumulator
}, [])
/* result 输出结果
0: (5) [1, 2, 3, 4, 5]
1: (2) [5, 6]
2: (2) [3, 4]
3: [1]
4: [19]
*/
const maxLength = result.reduce((previousValue, currentValue) => Math.max(previousValue, currentValue.length), 0)
console.log(maxLength) // 5

计算对象数组的属性求和

const arr = [
{ name: '张三1', age: 28 },
{ name: '张三2', age: 24 },
{ name: '张三3', age: 17 },
{ name: '张三4', age: 30 }
]
const result = arr.reduce((accumulator, currentValue) => accumulator += currentValue.age, 0)
console.log(result) // 99

将对象数组转换为键值对对象

const arr = [
{ name: '张三1', age: 28 },
{ name: '张三2', age: 24 },
{ name: '张三3', age: 17 },
{ name: '张三4', age: 30 }
]
const result = arr.reduce((accumulator, currentValue) => {
accumulator[currentValue.name] = currentValue.age
return accumulator
}, {})
console.log(result) // {张三1: 28, 张三2: 24, 张三3: 17, 张三4: 30}

计算数组中出现够次数最多的元素

const arr = [1, 2, 3, 4, 5, 5, 5, 6, 3, 4, 1, 19]
const result = arr.reduce((accumulator, currentValue) => {
accumulator[currentValue] = (accumulator[currentValue] || 0) + 1
return accumulator
}, {})
const maxCount = Math.max(...Object.values(result))
const res = Object.keys(result).filter(key => result[key] === maxCount).map(Number)
console.log(res) // [5]

实现Promise串行执行

const promise1 = () => Promise.resolve('one')
const promise2 = (input) => Promise.resolve(input + ' two')
const promise3 = (input) => Promise.resolve(input + ' three')

const result = [promise1, promise2, promise3].reduce((accumulator, currentValue) => {
return accumulator.then(currentValue)
}, Promise.resolve('start'))

result.then(console.log) // one two three

按属性对数组分组

const arr = [
{ name: '张三1', age: 28 },
{ name: '张三2', age: 24 },
{ name: '张三3', age: 17 },
{ name: '张三1', age: 30 }
]
const result = arr.reduce((accumulator, currentValue) => {
const key = currentValue.name
if (!accumulator[key]) {
accumulator[key] = []
}
accumulator[key].push(currentValue)
return accumulator
}, {})
console.log(result)
/*
张三1: Array(2) 0: {name: '张三1', age: 28}
1: {name: '张三1', age: 30}
张三2: Array(1) 0: {name: '张三2', age: 24}
张三3: Array(1) 0: {name: '张三3', age: 17}
*/

扁平化数组

不适合多层嵌套

const arr = [1, 2, [3, 4, 5, 5], 5, [6, 3, 4], 1, 19]
const result = arr.reduce((accumulator, currentValue) => {
if (Array.isArray(currentValue)) {
return accumulator.concat(currentValue)
}
accumulator.push(currentValue)
return accumulator
}, [])
console.log(result) // [1, 2, 3, 4, 5, 5, 5, 6, 3, 4, 1, 19]

合并对象

const arr1 = { a: '张三1', c: 17 }
const arr2 = { b: '张三2', d: 27 }
const arr3 = { a: '张三3', g: 37 }
const result = [arr1, arr2, arr3].reduce((accumulator, currentValue) => Object.assign(accumulator, currentValue), {})
console.log(result) // {a: '张三3', c: 17, b: '张三2', d: 27, g: 37}