如何合并2个对象并合并其中的数组

时间:2019-08-13 21:10:05

标签: javascript typescript

我有几个具有相同属性的对象。我想合并具有相同第一级键值的所有对象。我知道点差算子

    const obj3 = {...obj1, ...obj2}

但是问题是,对象内部的数组被覆盖并且没有合并。

{
  "id": 1,
  "name": "firstLevel",
  "visible": true,
  "subCategories": [
    {
      "id": 2,
      "name": "secondLevel",
      "visible": true,
      "skills": [
        {
          "name": "foo",
          "id": 5,
          "visible": true
        }
      ]
    }
  ]
}
{
  "id": 1,
  "name": "firstLevel",
  "visible": true,
  "subCategories": [
    {
      "id": 2,
      "name": "secondLevel",
      "visible": true,
      "skills": [
        {
          "name": "bar",
          "id": 1,
          "visible": true
        }
      ]
    }
  ]
}

我希望这些对象能够像这样组合:

{
  "id": 1,
  "name": "firstLevel",
  "visible": true,
  "subCategories": [
    {
      "id": 2,
      "name": "secondLevel",
      "visible": true,
      "skills": [
        {
          "name": "foo",
          "id": 5,
          "visible": true
        },
        {
          "name": "bar",
          "id": 1,
          "visible": true
        }
      ]
    }
  ]
}

1 个答案:

答案 0 :(得分:2)

您正在寻找lodash.mergeWith,它将以递归方式合并数组和纯对象属性。

var object = {
  'a': [{ 'b': 2 }, { 'd': 4 }]
};
 
var other = {
  'a': [{ 'c': 3 }, { 'e': 5 }]
};

function customizer(objValue, srcValue) {
  if (_.isArray(objValue)) {
    return objValue.concat(srcValue);
  }
}
 
_.mergeWith(object, other, customizer);
// => { 'a': [{ 'b': 2 }, { 'c': 3 }, { 'd': 4 }, { 'e': 5 }] }

对于特定情况,当您知道对象的ID时,此定制器功能将起作用as requested

function customizer(objValue, srcValue) {
  if (_.isArray(objValue)) {
    for (const srcItem of srcValue) {
      const objItem = objValue.filter(item => item.id === srcItem.id);
      if (objItem.length) {
        objValue = objValue.map(item => {
          if (item.id === objItem[0].id) {
            return _.mergeWith(item, srcItem, customizer);
          }

          return item;
        });
      } else {
        objValue = [...objValue, srcItem];
      }
    }

    return objValue;
  }
}