【问题标题】:If two different objects have same key name, merge their value如果两个不同的对象具有相同的键名,则合并它们的值
【发布时间】:2020-11-30 04:47:30
【问题描述】:
let obj1 = { names: ["Zack","Cody"]};
let obj2 = { names: ["John","Jake"] };

结果:obj1 = { names: ["Zack","Cody","John","Jake"]}

我尝试过的:

if (Object.keys(obj1) == Object.keys(obj2)) {
  Object.values(obj1) = [...Object.values(obj1), ...Object.values(obj2)];
}

【问题讨论】:

  • 为什么名字不合并?
  • obj1.names.push(...obj2.names)?您不能分配给像 Object.values() 这样的函数调用。
  • 其他未命名为names的键呢?
  • @kmoser 我重构了问题
  • @ggorlen 我刚刚尝试将该行放在 if 语句中,但 obj1 仍然只返回 Zack 和 Cody

标签: javascript object ecmascript-6


【解决方案1】:

遍历obj1 中的键,对于obj2 中存在的每个键,将其值合并到obj1

let obj1 = { names: ["Zack","Cody"]};
let obj2 = { names: ["John","Jake"] };

Object.keys(obj1).forEach(function(k) {
    if ( obj2[k] ) { // obj2 contains this key
        obj1[k].push( ...obj2[k] ) // Add the values from obj2's key to obj1's key
    }
});

【讨论】:

    【解决方案2】:

    如果该属性不存在,您可以迭代每个对象的属性并将它们添加到新对象中。为了处理其他对象中存在相同键的合并,我们可以定义一个合并策略函数来解决冲突。

    let obj1 = { names: ["Zack","Cody"]};
    let obj2 = { names: ["John","Jake"] };
    
    function mergeObjs(objects, mergeStrategy) {
        mergeStrategy = mergeStrategy || ((oldV, newV) => newV);
        const result = {};
        for (let ob of objects) {
            for (let [k, v] of Object.entries(ob)) {
                const oldV = result[k];
                result[k] = (oldV == undefined) ? v: mergeStrategy(oldV, v); 
            }
        }
        return result;
    }
    
    console.log(mergeObjs([obj1, obj2], (oldV, newV) => oldV.concat(newV)));
    

    该函数每次合并只允许一个策略,这对于更复杂的情况可能会有点限制,但对于像这样的简单情况就可以了。

    【讨论】:

      【解决方案3】:

      您可以通过包装到数组元素中并展平(或@ggorlen 在评论中建议的concat )来连接值

      let obj1 = { names: ["Zack", "Cody"] }
      let obj2 = { names: ["John", "Jake"] }
      
      const mergeObj = (obj1Raw = {}, obj2Raw = {}) => {
        // shallow clone for demo only
        let obj1 = { ...obj1Raw }
        let obj2 = { ...obj2Raw }
      
        for (const prop in obj2) {
          if (obj1.hasOwnProperty(prop)) {
            obj1[prop] = [obj1[prop], obj2[prop]].flat()
          } else {
            obj1[prop] = obj2[prop]
          }
        }
      
        return obj1
      }
      
      console.log(mergeObj(obj1, obj2))

      【讨论】:

      • 如果不支持.flat(),您可以使用[...obj1[prop], ...obj2[prop]]obj1[prop].concat(obj2[prop])
      【解决方案4】:

      你可以试试lodash.merge,强大的合并多个对象的功能

      var object = {
        'a': [{ 'b': 2 }, { 'd': 4 }]
      };
       
      var other = {
        'a': [{ 'c': 3 }, { 'e': 5 }]
      };
       
      _.merge(object, other);
      // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
      

      【讨论】:

        【解决方案5】:

        这是使用Object.entriesObject.fromEntriesArray#map 的单行代码,假设共享相同键名的属性始终是数组:

        let obj1 = { names: ["Zack","Cody"] };
        let obj2 = { names: ["John","Jake"] };
        
        const result = { 
          ...obj1, 
          ...Object.fromEntries(Object.entries(obj2).map(([k, v]) => [
            k, obj1[k] ? [...obj1[k], ...v] : v
          ]))
        };
        
        console.log(result);

        【讨论】:

        • @Mhmdrz_A Lol,典型的ES6滥用案例
        【解决方案6】:

        在您的代码中,您正在比较两个数组 - Object.keys(obj1)Object.keys(obj2)。这种情况永远不会成立,因为没有两个数组是相等的,因为它们引用了不同的内存位置。

        为了解决这个问题,你可以比较它们的内容。这就是我在下面的 sn-p 中所做的 -

        let obj1 = { names: ["Zack","Cody"]};
        let obj2 = { names: ["John","Jake"]};
        
        if (Object.keys(obj1)[0] ==  Object.keys(obj2)[0]) { 
          Object.values(obj1)[0].push(...Object.values(obj2)[0]);
          console.log(obj1.names); 
        }

        我只是在上面的 sn-p 中比较两个对象中的第一个键。如果您想对两个对象中的每个键都执行此操作,则可以使用带有索引的循环替换 [0]

        注意 - 如果您要使用上述方法,那么两个对象中键的顺序很重要。

        【讨论】:

        • 这不是我要找的,如果它们具有相同的键名,那是我想对 obj1 的值执行此操作的时候,因为我的对象具有不同的键名
        • @teestunna 你能检查我更新的答案并告诉我这是否能解决你的问题吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-28
        • 1970-01-01
        • 2018-02-22
        • 2018-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多