数组的reduce方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值。
reducer 函数接收4个参数:
- accumulator (acc) (累加器)
- current Value (cur) (当前值)
- current Index (idx) (当前索引)
- source Array (src) (源数组)
你的 reducer 函数的返回值分配给累加器,其值在数组的每个迭代中被记住,并最后成为最终的单个结果值。
注意:
- 1.回调函数第一次执行时,previousValue 和 currentValue 可以是一个值,如果 initialValue 在调用 reduce 时被提供,那么第一个 previousValue 等于 initialValue ,并且currentValue 等于数组中的第一个值;如果initialValue 未被提供,那么previousValue 等于数组中的第一个值,currentValue等于数组中的第二个值。
- 2.如果数组为空并且没有提供initialValue, 会抛出TypeError 。如果数组仅有一个元素(无论位置如何)并且没有提供initialValue, 或者有提供initialValue但是数组为空,那么此唯一值将被返回并且callback不会被执行。
使用场景:
- 1.数组求和、积:
[1,2,3,4].reduce((a, b) => a + b) // 10
[1,2,3].reduce(function(pre,cur,index,arr){return pre * cur}) // 6
复制代码
- 2.数组扁平化:
function flattMap(arr) {
return Array.isArray(arr)
? arr.reduce((acc, value) => [
...acc,
...flattMap(value)
], [])
: [arr];
}
flattMap([1, [2, 3], 1]); // [1, 2, 3, 1]
复制代码
- 3.对象过滤:
const pick = (obj, arr) => {
return arr.reduce((acc, curr) => {
if (curr in obj) {
acc[curr] = obj[curr];
return acc;
}
}, {})
}
pick({a: 1, b: 2}, ['a']) // { a: 1 }
复制代码
- 4.对象取值:
const a = { b: { c: { d: 2 }}}
const get = (obj, arr) => {
return arr.reduce((acc, curr) => {
return acc ? acc[curr] : null
}, obj)
}
get(a, ['b', 'c', 'd']) // 2
复制代码
实现reduce
Array.prototype.fakeReduce = function(fn, initialValue) {
if (typeof fn !== 'function') {
throw new TypeError('fn is not a function!');
}
// 保存原数组
let initialArr = this;
// 复制原数组
let arr = [...initialArr];
if (initialValue) arr.unshift(initialValue);
let index, newValue;
while (arr.length > 1) {
index = initialArr.length - arr.length + 1;
// 返回数组的前2项的计算结果
newValue = fn.call(null, arr[0], arr[1], index, initialArr);
// 将arr数组的前2项删除并将其计算结果推到arr数组的首部
arr.splice(0, 2, newValue);
}
return newValue;
};
复制代码
转载于:https://juejin.im/post/5bb099c6e51d450e4f38e121