1.参考:JS数组reduce()方法详解及高级技巧 - 简书 (jianshu.com)
(1) 数组操作-根据元素的key汇总数据 - SegmentFault 思否
2.reduce()环境要求:Google:Yes;IE:9.0↑; Firefox:3.0↑; opera:10.5↑
3.相比于官方解释,下述为个人简单理解
reduce 是对数组进行操作,
标准格式:let newArr = arr.reduce((pre,cur)=>{xxx},{})
其中 newArr 为预期结果;
arr 为目标数组;
xxx 为逻辑函数;
原理: pre,在初始时为原型{},也是代码最末尾那个{}标识,之后变为代码xxx中返回的结果,继续对arr中下一个元素进行操作;
4.简单用法
arr:[1,2,3,4]
求和:arr.reduce((prev,cur)=>prev+cur)
结果:10
乘积:arr.reduce((prev,cur)=>prev*cur)
结果:24
5.进阶用法
01:统计字符串出现次数
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let nameNum = names.reduce((pre,cur)=>{
if(cur in pre){
pre[cur]++
}else{
pre[cur] = 1
}
return pre
},{})
console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
02:数组去重
let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
if(pre.indexOf(cur) === -1){
return pre.concat(cur)
}else{
return pre
}
},[])
console.log(newArr);// [1, 2, 3, 4]
03:二维数组转一维
let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre,cur)=>{
return pre.concat(cur)
},[])
console.log(newArr); // [0, 1, 2, 3, 4, 5]
04:多维数组转一维
let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(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, 7]
05:数组相同项合并
let names = [
{ name: ["Alice"], code: "101" },
{ name: ["Bob"], code: "102" },
{ name: ["Alice"], code: "101" },
{ name: ["Tiff"], code: "101" },
{ name: ["Bruce"], code: "105" }
];
const arrMerge = names.reduce((pre, curr) => {
const eqIndex = pre.findIndex((item) => item.code === curr.code);
if (eqIndex !== -1) {
pre[eqIndex].name.push(...curr.name);
return pre;
} else {
return pre.concat(curr);
}
}, []);
console.log(arrMerge);
//[{code:'101',name:['Alice','Alice','Tiff']}, {code:'102',name:['Bob']}, {code:'105',name:['Bruce']}]
06:数组对象相同项求和
let arr = [
{ name: "ming", grade: 87 },
{ name: "hong", grade: 84 },
{ name: "jun", grade: 91 },
{ name: "jun", grade: 87 }
];
let newArr = arr.reduce((pre, cur) => {
//cur参数是否在pre数据中,有则>-1
let eqIndex = pre.findIndex((item) => item.name === cur.name);
if (eqIndex > -1) {
pre[eqIndex].grade += cur.grade;
return pre;
} else {
pre.push(cur);
return pre;
}
}, []);
console.log("newarr==", newArr);
// [
// { name: "ming", grade: 87 },
// { name: "hong", grade: 84 },
// { name: "jun", grade: 178 }
// ];