JavaScript中如何合并数组内同id对象的所有属性?
合并数组中同ID对象的属性值
首先,我明白你的需求:要根据Lot_id.id对数组里的对象分组,把同一ID下所有数值类型的属性(包括Lot_id内部的和外层的)累加合并,不同ID的对象则保留为独立条目。
问题重现
原始数组:
const array = [ { Lot_id:{ id:1, qty_receive:30, qty_return:5, qty_remain:15 }, qty_allocate:10, remaining_qty:20 }, { Lot_id:{ id:1, qty_receive:30, qty_return:5, qty_remain:15 }, qty_allocate:10, remaining_qty:20 }, { Lot_id:{ id:2, qty_receive:30, qty_return:5, qty_remain:15 }, qty_allocate:10, remaining_qty:20 } ];
预期结果:
const result = [ { Lot_id:{ id:1, qty_receive:60, qty_return:10, qty_remain:30 }, qty_allocate:20, remaining_qty:40 }, { Lot_id:{ id:2, qty_receive:30, qty_return:5, qty_remain:15 }, qty_allocate:10, remaining_qty:20 } ];
解决方案代码
这里用JavaScript的Array.reduce()方法实现,逻辑清晰且高效:
const mergeByLotId = (arr) => { // 用reduce创建临时对象,以id为键存储每个分组的合并数据 const grouped = arr.reduce((acc, current) => { const id = current.Lot_id.id; // 若当前id未创建分组,初始化结构 if (!acc[id]) { acc[id] = { Lot_id: { ...current.Lot_id }, qty_allocate: 0, remaining_qty: 0 }; } // 累加外层属性 acc[id].qty_allocate += current.qty_allocate; acc[id].remaining_qty += current.remaining_qty; // 累加Lot_id内部的数值属性 acc[id].Lot_id.qty_receive += current.Lot_id.qty_receive; acc[id].Lot_id.qty_return += current.Lot_id.qty_return; acc[id].Lot_id.qty_remain += current.Lot_id.qty_remain; return acc; }, {}); // 将临时对象的值转为数组,得到最终结果 return Object.values(grouped); }; // 测试调用 const mergedArray = mergeByLotId(array); console.log(mergedArray);
代码解释
- 分组初始化:通过
reduce遍历数组,以Lot_id.id作为键,初始化每个分组的对象结构,避免修改原始数据。 - 属性累加:分别对分组的外层属性(
qty_allocate、remaining_qty)和Lot_id内部的数值属性做累加操作。 - 结果转换:用
Object.values()把分组对象转换成数组,匹配预期的输出结构。
如果后续对象属性可能变动,还可以用通用版本自动识别数值属性累加:
const mergeByLotIdGeneric = (arr) => { const grouped = arr.reduce((acc, current) => { const id = current.Lot_id.id; if (!acc[id]) { // 简单深拷贝初始化分组(适合层级不深的结构) acc[id] = JSON.parse(JSON.stringify(current)); } else { // 遍历外层属性 for (const key in current) { if (typeof current[key] === 'number') { acc[id][key] += current[key]; } else if (typeof current[key] === 'object' && current[key] !== null) { // 遍历内层Lot_id属性,跳过id字段 for (const innerKey in current[key]) { if (typeof current[key][innerKey] === 'number' && innerKey !== 'id') { acc[id][key][innerKey] += current[key][innerKey]; } } } } } return acc; }, {}); return Object.values(grouped); };
这个版本无需手动指定属性名,会自动识别所有数值类型属性进行累加,适配更多场景。
内容的提问来源于stack exchange,提问作者Rekha
相关产品推荐
相关产品推荐

