首页 > 解决方案 > 使用 Lodash 将最后一个树节点合并到一个数组中

问题描述

设想:

const obj1 = {
  a: 100,
  b: 200,
  c: { c1: 100 }
}

const obj2 = {
  b: 250,
  c: { c1: 200 },
  d: { d1: { d1a: 400 } }
}

期望的结果:

someMergeFn(obj1, obj2)

// Should return...

{
  a: [100],
  b: [200, 250],
  c: { c1: [100, 200] },
  d: { d1: { d1a: [400] } }
}


我的尝试如下,但我无法接近预期的结果。

const obj1 = {
  a: 100,
  b: 200,
  c: { c1: 100 }
}

const obj2 = {
  b: 250,
  c: { c1: 200 },
  d: { d1: { d1a: 400 } }
}

const merged = _.mergeWith(
  obj1,
  obj2,
  (first, second) =>
    Array.isArray(first) ? first.push(second) : [first, second]
)

console.log(merged)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>

标签: javascriptarraysobjectmergelodash

解决方案


以空对象开始合并。这将防止第一个对象的突变,并将所有值作为空值开始,在这种情况下,我们将提供一个空数组作为first.

只要第二个值不是对象(或数组),我们就可以假设第一个值是一个数组,并使用 spread(或 concat)将它们组合成一个新数组。如果不是,我们返回undefined以便_.mergeWith()处理对象/数组的合并。

const obj1 = {"a":100,"b":200,"c":{"c1":100}}
const obj2 = {"b":250,"c":{"c1":200},"d":{"d1":{"d1a":400}}}

const merged = _.mergeWith(
  {},
  obj1,
  obj2,
  (first, second) =>
    !_.isObject(second) ? [...(first || []), second] : undefined
)

console.log(merged)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>


推荐阅读