如何对二级对象数组中选中项的同类型值求和?
二级数组按条件汇总quantity数值
我有一个二级结构的对象数组,示例代码如下:
let myArray = [ { "name": "Job 01", "isSelected": true, "Items": [ { "id" : 1, "name": "Shopping", "quantity": 100 }, { "id" : 3, "name": "Walking", "quantity": 20 }, { "id" : 5, "name": "Singing", "quantity": 20 } ] }, { "name": "Job 02", "isSelected": false, "Items": [ { "id" : 1, "name": "Shopping", "quantity": 100 }, { "id" : 3, "name": "Walking", "quantity": 20 }, { "id" : 5, "name": "Singing", "quantity": 20 } ] }, { "name": "Job 03", "isSelected": true, "Items": [ { "id" : 1, "name": "Shopping", "quantity": 20 }, { "id" : 5, "name": "Singing", "quantity": 10 } ] }, { "name": "Job 04", "isSelected": true, "Items": [] }, ]
需要得到的结果数组:
let finalArray = [ { "id" : 1, "name": "Shopping", "quantity": 120 }, { "id" : 3, "name": "Walking", "quantity": 20 }, { "id" : 5, "name": "Singing", "quantity": 30 } ]
需求说明:仅对isSelected为true的Job下的Items,按相同id/name的类型汇总quantity数值,想知道如何用reduce处理这种二级数组结构。
解决方案
可以分两步处理:先筛选出符合条件的Items数组,再用reduce汇总数量:
步骤1:提取所有选中Job的Items
先用filter筛选出isSelected: true的Job,再用flatMap把所有二级Items数组合并成一个一维数组,简化后续遍历:
const validItems = myArray .filter(job => job.isSelected) .flatMap(job => job.Items);
步骤2:用reduce汇总相同id/name的quantity
用reduce创建临时对象,以id为唯一键存储每个条目汇总后的信息,最后把对象的值转换成目标数组:
const finalArray = Object.values( validItems.reduce((acc, item) => { // 若当前id未在累加器中,初始化条目并重置quantity为0 if (!acc[item.id]) { acc[item.id] = {...item, quantity: 0}; } // 累加当前item的quantity acc[item.id].quantity += item.quantity; return acc; }, {}) );
完整代码
将两步合并,直接得到结果:
let myArray = [/* 你的原数组 */]; const finalArray = Object.values( myArray .filter(job => job.isSelected) .flatMap(job => job.Items) .reduce((acc, item) => { acc[item.id] = acc[item.id] || {...item, quantity: 0}; acc[item.id].quantity += item.quantity; return acc; }, {}) ); console.log(finalArray);
代码说明
filter(job => job.isSelected):仅保留选中状态的JobflatMap(job => job.Items):把所有选中Job的Items合并为一维数组,避免嵌套遍历reduce部分:- 空对象
acc作为累加器,存储以id为键的汇总条目 - 遍历每个item,若累加器中无对应id条目,则复制item并初始化quantity
- 累加当前item的quantity到对应条目
- 空对象
Object.values():将累加器对象的value提取为数组,得到最终格式
这样就能得到符合需求的汇总结果。
内容的提问来源于stack exchange,提问作者loveprogramming
相关产品推荐
相关产品推荐

