概念
reduce方法能搞定的东西,循环大多都能搞定;循环我们已经很了解了,看一下reduce吧! reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。本质上也是一个循环,不过在循环中保存了上次循环的状态。
语法及参数
array.reduce(callBack(total, currentValue, currentIndex, arr), initialValue)
- total 必需。上一次调用
callbackFn时的返回值。在第一次调用时,若指定了初始值则为初始值initialValue,否则为数组第一项array[0]; - currentValue 必需。当前元素。 在第一次调用,若指定了初始值initialValue,则值为array[0],否则从array[1]开始。
- currentIndex 可选。当前元素的索引。
- arr 可选。用于遍历的数组。
- initialValue 可选。传递给函数的初始值。
需要注意的事,对于空数组,不传初始值会报错。所以给定一个初始值总是保险的。
举例:数组求和
let sum = [1, 2, 3, 4].reduce((preVal, curVal) =>{
return preVal + curVal
}, 0) //10
常用案例
1.数组去重
let arr = ['a', 'b', 'c', 'd', 'e', 'e', 'd', 'c', 'd', 'b', 'a', 'd']
let arr2 = arr.reduce((preVal, curVal) => {
if (preVal.includes(curVal)) {
preVal.push(curVal)
}
return preVal
}, [])
2.数组扁平化
let arr = [0,[1], [2, 3], [4,[5,6]]]
const newArr = (arr)=>{
return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[])
}
console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6]
3.计算元素出现次数
let arr = ['a', 'b', 'c', 'd', 'e', 'e', 'd', 'c', 'd', 'b', 'a', 'd']
let countsObj = arr.reduce((obj, o) =>{
if (o in obj) {
obj[o]++
}
else {
obj[o] = 1
}
return obj
}, {})
4.对象里的属性求和
var arr = [
{
//...
score: 80
},
{
//...
score: 90
},
{
//...
score: 90
}
];
var sum = arr.reduce((prev, cur) =>{
return cur.score + prev;
}, 0);
console.log(sum) //270
原理
function myReduce(callback, initVal) {
let arr = this
if(!(arr instanceof Array)) {
throw (`${callback}.myReduce is not function`)
}
if(typeof callback != 'function') {
throw(`${callback} is not function`)
}
if(!arr.length) return;
let prev = initVal || arr[0];
let idx = initVal ? 0 : 1;
for(; idx<arr.length; idx++) {
prev = callback(prev, arr[idx], idx, arr)
}
return prev
}
使用myReduce代替reduce