Lodash _.merge功能问题

时间:2016-02-10 21:52:13

标签: javascript lodash

_ = require('lodash');

var a = [
  {
    'name': 'MyGroup',
    'description': null,
    'items': [
      {
        '_id': 'uStqrALmwWCdyzBnc',
        'type': 'endpoints'
      },
      {
        '_id': 'tpCSiT65R5PHmQ2yn',
        'type': 'endpoints'
      }
    ],
    '_id': '8phfSHKLt9c5SB2YM'
  }
];

var b = [
  {
    'name': 'MyGroup',
    'description': null,
    'items': [
      {
        '_id': 'GET_test',
        'type': 'endpoints'
      }
    ]
  }
];

console.log(JSON.stringify(_.merge(a, b), null, 2));

给出这个输出:

    [
  {
    "name": "MyGroup",
    "description": null,
    "items": [
      {
        "_id": "GET_test",
        "type": "endpoints"
      },
      {
        "_id": "tpCSiT65R5PHmQ2yn",
        "type": "endpoints"
      }
    ],
    "_id": "8phfSHKLt9c5SB2YM"
  }
]

反转a和b仅导致b对象,我可以理解无法以某种方式合并。但为什么这部分合并而不是完全合并?这是合乎逻辑还是错误?

2 个答案:

答案 0 :(得分:4)

这是合乎逻辑的。合并并不了解你对阵列的意图:它只是将你从第二个物体中的物品补丁到正确的位置,覆盖,不附加或者结束或其他东西。

你可能想要的是_.mergeWith,它允许你指定一个自定义函数来处理你想要的特殊情况。事实上,文档实际上描述了你可能正在处理的情况(想要一些特定的操作,比如,concat,当两个数组被合并时发生)https://lodash.com/docs#mergeWith

答案 1 :(得分:3)

我认为lodash的行为与设计一致。它尝试以递归方式合并您的对象,这意味着,要保证items数组中的对象应该合并在一起。所以,结果并不像我们预期的那样,但也许是合乎逻辑的。

使用_.mergeWith可能会更好运,提供一个处理_.union数组的自定义程序:

_.mergeWith(a, b, function(objValue, srcValue) { if (_.isArray(objValue)) { return _.union(objValue, srcValue); }})

或更容易阅读:

function customizer(objValue, srcValue) {
    if (_.isArray(objValue)) {
        return _.union(objValue, srcValue);
    }
}

_.mergeWith(a, b, customizer);

如果需要,可以使定制器功能更加智能化。