JavaScript数组去重并更新属性问题求助
解决JavaScript数组分组聚合问题
首先,咱们先聊聊你当前代码里的几个核心问题:
k变量未初始化就直接使用,会直接导致运行报错- 直接修改原数组元素的方式容易造成逻辑混乱,而且
arr.filter(item => item !== arr[i])的判断逻辑因为对象是引用类型,没法正确过滤重复项 - 整体逻辑没有清晰区分「销售数量总和」和「时长总和」的统计,导致最终的平均时长计算逻辑错误
接下来是完全符合你需求的解决方案,咱们用Array.reduce()来实现分组和聚合,这是处理这类数组转换最简洁高效的方式:
const handleData = (arr) => { // 第一步:用reduce按name分组,聚合需要计算的数值 const grouped = arr.reduce((acc, current) => { // 用name作为分组的唯一标识key const key = current.name; if (!acc[key]) { // 如果是该组第一个元素,复制基础属性并初始化统计值 acc[key] = { ...current, totalSold: current.numberSoldLodging, totalHours: current.numberHoursSpent }; } else { // 同组元素累加销售数量和时长 acc[key].totalSold += current.numberSoldLodging; acc[key].totalHours += current.numberHoursSpent; } return acc; }, {}); // 第二步:将分组对象转换为数组,计算最终的结果属性 return Object.values(grouped).map(item => { return { name: item.name, numberSoldLodging: item.totalSold, numberHoursSpent: Number((item.totalHours / item.totalSold).toFixed(2)), mail: item.mail, id: item.id, created: item.created, updated: item.updated }; }); }; // 测试你的原始数组 const originalArray = [ { name: "Sale Network 1", numberSoldLodging: 1, numberHoursSpent: 1, mail: "lanlehoang10@gmail.com", id: "5ceb9b5aff2d5732b4282886", created: 1558944602810, updated: 1558944602810 }, { name: "Sale Network 1", numberSoldLodging: 1, numberHoursSpent: 2, mail: "lanlehoang10@gmail.com", id: "5ceb9b5aff2d5732b4282886", created: 1558944602810, updated: 1558944602810 }, { name: "Sale Network 2", numberSoldLodging: 1, numberHoursSpent: 3, mail: "sale2@gmail.com", id: "5cef5a62b9c3113764e2183b", created: 1559190114548, updated: 1559190114548 }, { name: "Sale Network 1", numberSoldLodging: 1, numberHoursSpent: 4, mail: "lanlehoang10@gmail.com", id: "5ceb9b5aff2d5732b4282886", created: 1558944602810, updated: 1558944602810 }, { name: "Sale Network 2", numberSoldLodging: 3, numberHoursSpent: 5, mail: "lanlehoang10@gmail.com", id: "5ceb9b5aff2d5732b4282886", created: 1558944602810, updated: 1558944602810 } ]; console.log(handleData(originalArray));
代码逻辑拆解:
分组聚合阶段:
- 用
reduce遍历原始数组,以name为键创建分组对象,确保同name的元素被归为一组 - 每组初始化时复制当前对象的所有基础属性,同时新增
totalSold和totalHours两个临时变量,分别用于累加销售数量和时长 - 遇到同组的后续元素时,直接对这两个临时变量进行累加
- 用
结果转换阶段:
- 用
Object.values()把分组后的对象转换成数组格式 - 遍历每个分组对象,计算最终的
numberHoursSpent(总时长 ÷ 总销售数),并用toFixed(2)保留两位小数(你可以根据需求调整精度) - 组装最终需要的属性,去掉临时的统计变量,得到你想要的结果结构
- 用
这个方案逻辑清晰,不会修改原始数组,避免了不必要的副作用,运行后就能得到完全符合要求的结果啦。
内容的提问来源于stack exchange,提问作者聖杯ツグミ
相关产品推荐
相关产品推荐

