如何用Lodash/Underscore按唯一属性合并嵌套对象数组?
用Lodash的_.groupBy + _.mergeWith轻松解决多层数据合并问题
当然可以用这两个方法的组合来搞定你的需求!完全不用写繁琐的嵌套循环,思路非常清晰,我给你一步步拆解怎么实现:
核心思路
- 先分组:用
_.groupBy把所有对象按照「层级属性」聚成一组——也就是那些用来判断“是否匹配”的属性(比如除了items之外的所有属性,或者你指定的特定层级键)。 - 再合并:对每个分组里的对象,用
_.mergeWith自定义合并规则,把它们的items数组拼接在一起,其他层级属性直接保留(因为同组的层级属性肯定是一致的)。
具体代码示例
假设你的原始数据是这样的(模拟多层层级+items数组的结构):
const dataArr = [ { category: 'electronics', type: 'phone', items: ['iPhone', 'Samsung'] }, { category: 'electronics', type: 'phone', items: ['Xiaomi', 'Huawei'] }, { category: 'electronics', type: 'laptop', items: ['MacBook', 'ThinkPad'] }, { category: 'home', type: 'kitchen', items: ['Oven', 'Microwave'] } ];
步骤1:定义分组规则
先写一个函数,用来生成每个对象的分组key——这里我们把除了items之外的层级属性转换成字符串,作为分组依据:
const getGroupKey = (obj) => { // 解构出items,剩下的就是层级属性 const { items, ...levelProps } = obj; return JSON.stringify(levelProps); };
如果你的层级是固定的几个属性(比如只看category和type),也可以直接拼接字符串,效率更高:
const getGroupKey = (obj) => `${obj.category}-${obj.type}`;
步骤2:分组+合并
用_.groupBy分组后,再用_.map遍历每个分组,用_.mergeWith合并组内的对象:
// 第一步:按层级分组 const groupedData = _.groupBy(dataArr, getGroupKey); // 第二步:合并每组的items数组 const finalResult = _.map(groupedData, (group) => { return _.mergeWith({}, ...group, (objValue, srcValue) => { // 当合并的是数组时,把两个数组合并 if (_.isArray(objValue)) { return objValue.concat(srcValue); } // 非数组属性用默认merge逻辑(同层级属性值一致,直接覆盖没问题) }); });
最终结果
运行后finalResult会变成:
[ { category: 'electronics', type: 'phone', items: ['iPhone', 'Samsung', 'Xiaomi', 'Huawei'] }, { category: 'electronics', type: 'laptop', items: ['MacBook', 'ThinkPad'] }, { category: 'home', type: 'kitchen', items: ['Oven', 'Microwave'] } ]
如果你用Underscore怎么办?
Underscore没有_.mergeWith,但可以用_.reduce来实现合并逻辑:
const groupedData = _.groupBy(dataArr, getGroupKey); const finalResult = _.map(groupedData, (group) => { return _.reduce(group, (result, item) => { // 合并items数组 result.items = (result.items || []).concat(item.items); // 初始化层级属性(用组内第一个对象的属性即可) if (!result.category) { result.category = item.category; result.type = item.type; } return result; }, {}); });
这个方案完全避开了嵌套循环,代码简洁易维护,完美适配你的需求~
内容的提问来源于stack exchange,提问作者JSess
相关产品推荐
相关产品推荐

