reduce 方法
- 定义:对数组中的每个元素执行一个自定义的累计器,将其结果汇总为单个返回值
- 形式:
array.reduce((acc,cur,index,srcArray)=>{},initialValue)
- 参数:
- callback:回调函数(必选参数)
- initialValue:初始值(可选),如果不传初始值, reduce 方法会从索引为 1 处开始执行回调,如果传入初始值,将从索引为 0 处开始执行回调,并从初始值的基础上累计。
注意:在没有初始值的空数组上调用 reduce 方法将报错。
- 回调函数的参数:
acc
:累计器,完成计算的返回值(必选参数),它是上一次调用回调时返回的累计值,或 initialValuecur
:当前被执行的数组元素(必选参数)index
:当前被执行的数组元素的索引(可选)srcArray
:原数组,也就是调用 reduce 方法的数组(可选)
- 流程:
- 以 acc 作为累计结果的初始值,不设置 acc 则以数组第一个元素为初始值
- 开始遍历,使用累计器处理 cur,将 cur 的映射结果累计到 acc 上,结束此次循环,返回 acc
- 进入下一次循环,直至数组最后一个元素
- 结束遍历,返回最终的 acc
应用场景一:统计数组中每一项出现的次数
const names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
//此处累计器为 pre, 当前元素为 cur
const nameNum = names.reduce((pre,cur)=>{
if(cur in pre){
pre[cur]++
}else{
pre[cur] = 1
}
return pre
//初始值 initialValue 为 {}
},{})
console.log(nameNum) //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
应用场景二:对象数组去重,并统计每一项重复的次数
const list = [
{ name: 'A', width: 20 },
{ name: 'B', width: 70 },
{ name: 'B', width: 70 },
{ name: 'C', width: 10 },
{ name: 'A', width: 20 },
{ name: 'A', width: 20 },
];
//初始化空对象,存放重复出现的次数
const repeatTime = {};
//此处累计器为 array, 当前元素为 item
const result = list.reduce((array, item) => {
//如果 repeatTime 已经有 item.name 这个变量
//这里repeatTime[item.name] 的值可以为'A'/'B'/'C'
if (repeatTime[item.name]) {
//已存在作为 repeatTime 的 key 对应的 value 值自增 1
repeatTime[item.name]++;
return array;
}
// repeatTime 中不存在的key 的 value 计数为 1
repeatTime[item.name] = 1;
return [...array, item];
//初始值 initialValue 为 []
}, []);
//输出
//repeatTime:{A: 3, B: 2, C: 1}
//result: [
// {name: 'A', width: 20}
// {name: 'B', width: 10}
// {name: 'C', width: 10}
//]
应用场景三:对象数组里属性求和
const result = [
{
subject: 'math',
score: 10
},
{
subject: 'chinese',
score: 20
},
{
subject: 'english',
score: 30
}
];
//此处累计器为 prev,当前元素为 cur
const sum = result.reduce((prev, cur) => {
return cur.score + prev;
//初始值 initialValue 为 0
}, 0);
console.log(sum) //60
此外还有各种用法,用途很广
reduce 可以参考这篇博客
25个你不得不知道的数组 reduc 高级用法——JowayYoung
数组的其他操作可以参考这篇博客
javascript你不一定知道的进阶(干货)实用技巧——陶醉的松鼠
JS 常用的数组方法整理
超全的JS常用数组方法整理——Sela
扩展:
JS常用的循环遍历