【问题标题】:Use mergeWith of Lodash with nested objects将 Lodash 的 mergeWith 与嵌套对象一起使用
【发布时间】:2019-05-11 09:07:10
【问题描述】:

我有两个这样的对象:

const object1 = {first: [{a: 0, b:3}], second: [{a: 1, b:2}], third: [{a: 3, b:2}]}
const object2 = {first: [{a: 1, b:0}], second: [{a: 10, b:0}], third: [{a: 2, b:3}]}

我想要这两个对象的总和:

const res = {first: [{a: 1, b:3}], second: [{a: 11, b:2}], third: [{a: 5, b:5}]}

我尝试以这种方式使用 Lodash 的 mergeWith:

const res = mergeWith({}, object1, object2, add)

但我明白了:

{first: NaN, second: NaN, third: NaN}

如何将 mergeWith 用于嵌套对象?

【问题讨论】:

  • add 函数在做什么?
  • 是Lodash的添加功能
  • 啊,我明白了。我没有意识到您正在单独导入这些功能。在这种情况下,它将无法工作,因为它会尝试将 array 添加到另一个数组中,这会导致 NaN,如您所见。
  • @vlaz 好的,有什么解决方法吗?
  • 数组中是否总是只有一个对象?我的意思是first: [{a: 0, b:3}] - 如果数组中有两个条目,那么合并逻辑可能会更复杂。或者可能不是 - 如果您希望合并匹配的索引。

标签: javascript merge lodash


【解决方案1】:

在执行mergeWith 时,您需要传递自定义程序。 Lodash 然后对值进行递归合并。

诀窍在于,如果您的定制器返回undefined,那么merge 将用于组合这些值。但是,由于 add 为不兼容的值返回 NaN,因此使用该值代替 - 因此,如果您只有一个像 add 一样工作但返回 undefined 而不是 NaN 的函数,那么 mergeWith 就可以了为您完成所有繁重的工作:

const object1 = {first: [{a: 0, b:3}], second: [{a: 1, b:2}], third: [{a: 3, b:2}]}
const object2 = {first: [{a: 1, b:0}], second: [{a: 10, b:0}], third: [{a: 2, b:3}]}

const res = _.mergeWith({}, object1, object2, customizer)

console.log(res);

function customizer(a, b) {
  // you can still use add
  const result = _.add(a, b);
  
  // ignore NaN values and return undefined instead
  if (_.isNaN(result)) { 
    return;
  }
  
  //only combine values that can be combined
  return result;
}
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>

另一种更短的表达方式是使用defaultTo

const object1 = {first: [{a: 0, b:3}], second: [{a: 1, b:2}], third: [{a: 3, b:2}]}
const object2 = {first: [{a: 1, b:0}], second: [{a: 10, b:0}], third: [{a: 2, b:3}]}

const customizer = (a, b) => _.defaultTo(_.add(a, b), undefined)

const res = _.mergeWith({}, object1, object2, customizer)

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

【讨论】:

    【解决方案2】:

    定义如何添加对象起到了作用:

    const res = mergeWith(object1, object2, (objValue, srcValue) =>
        [{
            a: objValue[0].a + srcValue[0].a,
            b: objValue[0].b + srcValue[0].b
        }]
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多