如何编写lodash _.mergeWith的customizer函数实现对象转数组合并
对象合并自定义规则实现
场景说明
现有两个待合并对象:
var obj3 = { customer_id: 1, products: { id: 1, name: "Car" }, }; var obj4 = { customer_id: 1, products: { id: 2, name: "Dress" }, };
期望合并后输出结果:
result = { customer_id: 1, products: [ { id: 1, name: "Car" }, { id: 2, name: "Dress" }, ], };
核心需求是编写customizer自定义合并函数,也可使用其他原生方案实现。
方案1:基于lodash mergeWith 的customizer实现
该场景是lodash.mergeWith的典型适用场景,自定义函数逻辑如下:
function customizer(objValue, srcValue, key) { // 精准匹配products字段做特殊处理,避免影响其他对象属性 if (key === 'products') { // 如果原值已经是数组则追加新值,否则将新旧两个对象组装为数组 return Array.isArray(objValue) ? [...objValue, srcValue] : [objValue, srcValue]; } // 其余字段走默认合并逻辑,不需要额外返回值 } // 调用时传入空对象作为目标容器,避免修改原对象 const result = _.mergeWith({}, obj3, obj4, customizer);
如果需要让所有同名对象属性都自动合并为数组,也可以把key判断替换为类型判断:
function customizer(objValue, srcValue) { if (_.isPlainObject(objValue) && _.isPlainObject(srcValue)) { return Array.isArray(objValue) ? [...objValue, srcValue] : [objValue, srcValue]; } }
方案2:原生JS实现(无需依赖lodash)
不需要引入第三方库的情况下,可以直接遍历对象属性手动合并:
function customMerge(...sources) { const target = {}; for (const source of sources) { for (const [key, value] of Object.entries(source)) { // 属性不存在时直接初始化 if (!target.hasOwnProperty(key)) { target[key] = value; continue; } // 针对products属性做数组合并处理 if (key === 'products' && typeof value === 'object' && value !== null) { if (!Array.isArray(target[key])) { target[key] = [target[key]]; } target[key].push(value); continue; } // 其余基础类型属性直接覆盖(本场景下customer_id值一致,无冲突) target[key] = value; } } return target; } // 调用 const result = customMerge(obj3, obj4);
内容的提问来源于stack exchange,提问作者Giang An
相关产品推荐
相关产品推荐

