合并两个嵌套对象数组,相同name属性对应子数组拼接如何实现
嵌套结构按name属性合并实现方案
完整实现代码
import { mergeWith, keyBy, isArray, isObject, has } from 'lodash'; // 自定义递归合并规则 function customMerge(source, target) { function customizer(objVal, srcVal) { // 匹配需要按name分组合并的数组结构 if (isArray(objVal) && isArray(srcVal) && objVal.every(item => isObject(item) && has(item, 'name')) && srcVal.every(item => isObject(item) && has(item, 'name'))) { const objMap = keyBy(objVal, 'name'); const srcMap = keyBy(srcVal, 'name'); const allNames = new Set([...Object.keys(objMap), ...Object.keys(srcMap)]); return Array.from(allNames).map(name => { const objItem = objMap[name]; const srcItem = srcMap[name]; // 相同name的项递归合并 if (objItem && srcItem) { return mergeWith({}, objItem, srcItem, customizer); } // 无匹配name的项直接保留 return objItem || srcItem; }) } // 普通数组直接拼接 if (isArray(objVal) && isArray(srcVal)) { return objVal.concat(srcVal); } } // 传入空数组避免修改原对象 return mergeWith([], source, target, customizer); } // 调用示例 const merged = customMerge(sourceObj, targetObj);
实现逻辑说明
- 利用
mergeWith支持自定义合并规则且递归执行的特性,每一层属性合并都会触发自定义规则判断 - 碰到数组元素都带
name属性的结构时,先按name做分组映射,相同name的对象继续递归合并内部属性,不同name的对象直接加入结果集 - 无嵌套结构的普通数组直接执行拼接操作
- 非数组类型属性走lodash默认合并逻辑,不会修改原有属性值
内容的提问来源于stack exchange,提问作者Yumie
相关产品推荐
相关产品推荐

