【问题标题】:Merge two JavaScript Objects and conflicting properties合并两个 JavaScript 对象和冲突的属性
【发布时间】:2020-07-23 00:39:10
【问题描述】:

假设我有两个对象:

var obj1 = {cars: 'ford', fruit: 'peach', other: ['bar']}
var obj2 = {cars: 'ferrari', info: 'foo', other: ['baz']}

现在我想合并这两个对象和任何冲突的属性。预期结果:

{cars: ['ford', 'ferrari'], fruit: 'peach', info: 'foo', other: ['bar', 'baz']}

但是,使用对象传播

{...obj1, ...obj2}

返回

{cars: 'ferrari', fruit: 'peach', info: 'foo', other: ['baz']}

有没有办法合并两个对象并将冲突的属性合并到数组中而不是覆盖?
注意:我需要纯 JS

【问题讨论】:

  • 您必须手动循环遍历对象的项目并创建新对象
  • @rzwnahmd 你能提供一个函数来做到这一点吗?
  • 有一个答案显示了一种纯 JavaScript 的方法。 Lodash 库确实使代码更简洁。
  • @VLAZ 抱歉,我需要使用纯 javascript 来执行此操作...
  • 您描述的数据结构是一个多图,以防您想围绕该主题进行更多搜索。

标签: javascript node.js merge javascript-objects


【解决方案1】:

这是我的版本:)

var obj1 = {cars: 'ford', fruit: 'peach', other: ['bar']}
var obj2 = {cars: 'ferrari', info: 'foo', other: ['baz']}

var merge = (acc, [k, v]) => {
  if (k in acc) {
    acc[k] = [acc[k]].flat().concat(v)
  } else {
    acc[k] = v;
  }

  return acc;
}

var res = Object.entries(obj1).reduce(merge, obj2);

【讨论】:

    【解决方案2】:

    这个应该也可以:

    function mergeObject(o1, o2) {
      return {
        ...o2,
        ...Object.keys(o1).reduce((r, c) => ({
          ...r, [c]: o2.hasOwnProperty(c) ? [
            ...(Array.isArray(o1[c]) ? o1[c] : [o1[c]]),
            ...(Array.isArray(o2[c]) ? o2[c] : [o2[c]]),
          ] : o1[c]
        }), {})
      }
    }
    
    var obj1 = { cars: 'ford', fruit: 'peach', other: ['bar'] }
    var obj2 = { cars: 'ferrari', info: 'foo', other: ['baz'] }
    const result = mergeObject(obj1, obj2)
    console.log(result)
    

    【讨论】:

      【解决方案3】:

      您只需要手动编写代码,没有自动方法可以进行这种类型的合并。而且,由于您要合并数组的方式,它需要一些特殊条件:

      var obj1 = {cars: 'ford', fruit: 'peach', other: ['bar']}
      var obj2 = {cars: 'ferrari', info: 'foo', other: ['baz']}
      
      function merge(obj1, obj2) {
          let result = Object.assign({}, obj1);
          for (let [key, value] of Object.entries(obj2)) {
              if (result.hasOwnProperty(key)) {
                  if (!Array.isArray(result[key])) {
                      // target isn't an array yet, have to convert it to an array
                      result[key] = [result[key]];
                  }
                  // now copy over either a single entry or an array of entries
                  if (Array.isArray(obj2[key])) {
                      // copy all the array entries over to the other array
                      result[key].push(...obj2[key]);
                  } else {
                      // copy single entry over to the other array
                      result[key].push(obj2[key]);
                  }
              } else {
                  // result doesn't have this property yet, just copy the value over
                  result[key] = value;
              }
          }
          return result;
      }
      
      console.log(merge(obj1, obj2));

      【讨论】:

        【解决方案4】:

        您可以按属性合并并检查目标是否不是数组或值是否为数组。

        const
            merge = (target, source) => Object.entries(source).reduce((o, [k, v]) => {
                if (k in o) {
                    if (!Array.isArray(o[k])) o[k] = [o[k]];
                    [].concat(v).forEach(item => {
                        if (!o[k].includes(item)) o[k].push(item);
                    });
                } else {
                    o[k] = v;
                }
                return o;
            }, target);
        
        var obj1 = { cars: 'ford', fruit: 'peach', other: ['bar'] },
            obj2 =  {cars: 'ferrari', info: 'foo', other: ['baz'] },
            result = [obj1, obj2].reduce(merge, {});
        
        console.log(result);

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-05
          • 1970-01-01
          • 2023-03-16
          • 1970-01-01
          相关资源
          最近更新 更多