reduce()
reduce 方法对数组的每个元素执行提供的reducer函数,将结果汇为单个返回值。
使用
arr.reduce(callback(accumulator, currentValue, index, array), initialValue)
reducer
callback 执行数组中每个值的函数,包括四个参数。
accumulator
累计,累计回调的返回值。上一次回调返回的累计值。 问题,累计值的初始值时如何选取的?
currentValue 当前值数组中正在处理的元素
index
索引,当前正在处理数组的索引值。如果提供了initialValue,索引号为0,否则索引从1开始。提供了初始值,迭代次数为arr.length,未提供初始值,迭代次数为arr.length - 1。第一次回调把数组第一个元素作为累加初始值,并从索引为1的元素开始迭代。
array 调用reduce()的函数。
initialValue 初始值
1、如果提供了初始值,将作为第一次调用callback函数时的第一个参数值(ACCUMULATOR)的值。 2、如果没有提供初始值,则把数组第一个值作为callback第一个参数的值。 注意点就是是否将初始值作为第一次调用callback函数的累加值。
应用
数组累加
数据累加,设置初始值,初始值。
let sum = [1, 2, 3, 5].reduce((acc, current) => {
return acc + current
}, 0)
对象属性和
let sum = [{x: 1}, {x: 3}, {x: 5}, {x: 6}].reduce((acc, current) => {
return acc + current.x
}, 0)
Promise 队列
let promiseFn = function () {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('resolve1')
resolve()
}, 1000)
})
}
let promiseFn2 = function () {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('resolve2')
resolve()
}, 1000)
})
}
let promiseFn3 = function () {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('resolve3')
resolve('last resolve')
}, 1000)
})
}
let pro = [promiseFn, promiseFn2, promiseFn3].reduce((p, f) => {
return p.then(f)
}, Promise.resolve()) // 提供initialValue,从第一个参数遍历
pro.then(res => {
console.log('res', res)
})
计算数组中每个元素出现的次数
需要注意的是需要提供一个初始值{}来承接每次循环的返回值
let names = ['alice', 'Bob', 'lee', 'mark']
let nameNum = names.reduce((acc, cur) => {
if (!acc[cur]) {
acc[cur] = 1
} else {
acc[cur]++
}
return acc
}, {})
数组去重
let arr = ['1', '2', '2', '3', '4'].reduce((acc, cur) => {
if (!acc.includes[cur]) {
return acc.concat(cur)
}
return acc
}, [])
// 当然还可以使用new set
// Array.from 从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
Array.from(new Set(myArray))
二维数组转行成一维数组
let arr = [['1', '2'], ['3', '4']].reduce((acc, cur) => {
return acc.concat(cur)
}, [])
多维数组转换成一维数组
采用递归的思路处理
let arr1 = [[0, 1], [2, 3], [4, [5, 6, 7]]]
const flattenArr = function (arr) {
return arr.reduce((acc, cur) => {
return acc.concat(Array.isArray(cur) ? flattenArr(cur) : cur)
}, [])
}
console.log(flattenArr(arr1))
总结
reduce的参数为callback、initialValue,callback具有四个参数。第一个参数accumulator累计值,currentValue、index,arr。当设置了初始值,index从0开始,且作为第一次回调的accumulator的初始值。当未提供initialValue时,index从1开始,且数组第一个参数作为第一次回调的累计值初始值,迭代次数也少一次。 借助reduce可以很方便的实现promise异步链、扁平化数组、数组去重、求和等。