You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Lodash合并嵌套对象:按id和sndid分组结构化数据

解决嵌套对象按id和sndid分组合并的问题

你之前的代码之所以只得到最后一个对象,核心原因是每次循环都把当前val的属性直接覆盖到同一个全局的assignedobject上,后面的对象会把前面的属性全部冲掉,自然只剩最后一个结果。咱们换个思路:先按id和sndid作为唯一标识分组,再把同一组内的所有零散属性合并到一个对象里。

实现步骤

  1. 先把所有嵌套的数组彻底扁平化,把藏在深层的单个对象都取出来
  2. 用id+sndid组合成唯一键(比如${id}-${sndid}),作为分组的依据
  3. 对每个分组里的对象进行属性合并,把所有零散的字段整合到一个对象中

具体代码实现

这里用Lodash的几个工具函数就能轻松搞定,代码可读性也高:

const result = { 
  '1': { 
    'a': [ 
      { id: '1', sndid: 'a', type: 'ios', value: '55', weight: 2 }, 
      { id: '1', sndid: 'a', sumvalue: 2 }, 
      { id: '1', sndid: 'a'}, 
      { id: '1', sndid: 'a', calcsum: '3' } 
    ], 
    '2': [ 
      { id: '1', sndid: 'b', type: 'ios', value: '55', weight: 3 }, 
      { id: '1', sndid: 'b', sumvalue: 3 }, 
      { id: '1', sndid: 'b'}, 
      { id: '1', sndid: 'b', calcsum: '7' } 
    ] 
  }, 
  '3': { 
    'a': [ 
      { id: '3', sndid: 'a', type: 'ios', value: '55', weight: 23}, 
      { id: '3', sndid: 'a', sumvalue: 4 }, 
      { id: '3', sndid: 'a', sumvalue_old: '4' }, 
      { id: '3', sndid: 'a', calcsum: '5' } 
    ] 
  } 
};

// 第一步:把所有嵌套的对象数组扁平化,得到所有单个对象的集合
const allItems = _.flatMapDeep(result, (obj) => _.flatMap(obj));

// 第二步:按id和sndid的组合键分组
const groupedItems = _.groupBy(allItems, item => `${item.id}-${item.sndid}`);

// 第三步:合并每组内的所有对象,把相同分组的属性整合到一起
const mergedObjects = Object.values(groupedItems).map(group => _.merge({}, ...group));

console.log(mergedObjects);

运行结果

执行后你会得到符合预期的合并数组,每个对象都包含对应id和sndid的所有属性:

[
  { id: '1', sndid: 'a', type: 'ios', value: '55', weight: 2, sumvalue: 2, calcsum: '3' },
  { id: '1', sndid: 'b', type: 'ios', value: '55', weight: 3, sumvalue: 3, calcsum: '7' },
  { id: '3', sndid: 'a', type: 'ios', value: '55', weight: 23, sumvalue: 4, sumvalue_old: '4', calcsum: '5' }
]

补充说明

如果需要对某些属性做计算(比如你期望结果里的values、sumvalue求和),可以在合并后或者合并过程中加上对应的逻辑。比如要把sumvalue累加的话,可以把_.merge换成自定义的合并函数:

const mergedObjects = Object.values(groupedItems).map(group => {
  return group.reduce((acc, curr) => {
    // 对sumvalue做累加
    if (curr.sumvalue) {
      acc.sumvalue = (acc.sumvalue || 0) + curr.sumvalue;
    }
    // 其他属性直接赋值(如果不存在的话)
    return {...acc, ...curr};
  }, {});
});

这样就能根据需求灵活处理属性的计算逻辑了。

内容的提问来源于stack exchange,提问作者Ckappo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:00:34