【问题标题】:How to merge the arrays in two objects by key (Javascript)如何按键合并两个对象中的数组(Javascript)
【发布时间】:2021-06-16 01:36:06
【问题描述】:

我正在尝试编写一个通过键合并两个对象的函数。这两个对象都有一个数字数组作为它们的值对,这是我要合并的数组。

这个函数的输入是

const obj1 = {
  foo: [1, 2],
  bar: [3],
  baz: [4],
};

const obj2 = {
  foo: [5],
  baz: [6, 7],
};

输出应该是

{
  foo: [1, 2, 5],
  bar: [3],
  baz: [4, 6, 7]
}

我尝试使用 concat 和 spread 运算符,但是我得到的答案是缺少第二个对象的 foo 中的“5”。另外,我注意到我目前的方法,如果键/值对只存在于 obj2 中,它不会被复制。有没有更好的方法来解决这个问题?这是我的代码,请帮忙!

function mergeByKey(obj1, obj2) {
  let resultObj = {};
  for (let key1 in obj1) {
    for (let key2 in obj2) {
      if (key1 === key2) {
        resultObj[key1] = [...obj1[key1], ...obj2[key1]];
      } else {
        resultObj[key1] = obj1[key1];
      }
    }
  }
  return resultObj;
}
**Output from code** 
{ foo: [ 1, 2 ], bar: [ 3 ], baz: [ 4, 6, 7 ] }

【问题讨论】:

    标签: javascript arrays javascript-objects


    【解决方案1】:

    不是最优雅的解决方案,但它似乎有效

    function mergeObjects(obj1, obj2){
            var response = {}
        
        for (let key in obj1) {
             response[key] = mergeProperty(obj1, obj2, key);
        }
    
    
        for (let key in obj2) {
             response[key] = mergeProperty(obj1, obj2, key);
        }
        
        return response;
    }
    
    function mergeProperty(obj1, obj2, property){
            let response = [];
        
        if(obj1.hasOwnProperty(property)){
                response = [...response, ...obj1[property]]
        }   
        
        if(obj2.hasOwnProperty(property)){
                response = [...response, ...obj2[property]]
        }
        
        return response;
    }
    
    const o1 = {
      foo: [1, 2],
      bar: [3],
      baz: [4],
    };
    
    const o2 = {
      foo: [5],
      baz: [6, 7],
    };
    
    console.log(mergeObjects(o1, o2))

    【讨论】:

      【解决方案2】:

      您可以从两个对象中获取不同的键数组,然后迭代该数组并检查一个对象而不是另一个对象中的键 - 因此获取该数组,或者如果键在两个对象中,则合并数组。

      见下文:

      const obj1 = {
        foo: [1, 2],
        bar: [3],
        baz: [4],
      };
      
      const obj2 = {
        foo: [5],
        baz: [6, 7],
      };
      
      //The output should be
      //{
      //  foo: [1, 2, 5],
      //  bar: [3],
      //  baz: [4, 6, 7]
      //}
      
      // keys from both objects, unique
      const allKeys = [... new Set(Object.keys(obj1).concat(Object.keys(obj2)))];
      
      // iterate all keys
      const result = allKeys.reduce((a, c) => {
        if (obj1[c] && !obj2[c]) a[c] = obj1[c];
        if (!obj1[c] && obj2[c]) a[c] = obj2[c];
        if (obj1[c] && obj2[c]) a[c] = obj1[c].concat(obj2[c]);
        return a;
      }, {});
      
      console.log(result);

      【讨论】:

        【解决方案3】:

        您可以使用扩展语法... 将两个对象合并为一个,当您在合并对象上使用Object.keys() 时,这将为您提供两个对象的键。然后,您可以在这个键数组上使用.reduce() 来创建一个新对象。对于每个键,您可以从 obj1 获取数组(如果不存在,则使用 || [] 将其默认为空数组),与来自 obj2 的数组连接(如果它不存在,您也可以将其默认为一个空数组):

        const obj1 = { foo: [1, 2], bar: [3], baz: [4], };
        const obj2 = { foo: [5], baz: [6, 7], };
        
        const merged = {...obj1, ...obj2};
        const res = Object.keys(merged).reduce((acc, key) => ({
          ...acc,
          [key]: (obj1[key] || []).concat(obj2[key] || [])
        }), {});
        
        console.log(res);

        【讨论】:

          【解决方案4】:

          尝试这样的事情(假设您不知道对象键并且值始终是数组)。

          function merge(x,y) {
            const keys = new Set([...Object.keys(x), ...Object.keys(y)]);
            const merged = {};
            for ( const k of keys ) {
              merged[k] = [ ...(x[k] || []), ...(y[k] || []) ];
            }
            return merged;
          }
          

          【讨论】:

            【解决方案5】:

            var obj1 = { foo: [1, 2], bar: [3], baz: [4] },
                obj2 = { foo: [5], baz: [6, 7] },
              merged = Object.create( obj1 );
            
            for( var x in obj2 )
                merged[ x ] = obj1[ x ].concat( obj2[ x ] )
            ;
            console.log( merged )
            ;

            【讨论】:

              【解决方案6】:

              你可以这样做......

              const
                obj1 = { foo: [ 1, 2 ], bar: [ 3 ], baz: [ 4 ] } 
              , obj2 = { foo: [ 5 ], baz: [ 6, 7] } 
              , obj3 = { foo: [ 6 ], bar: [11], baz: [ 33, 14] } 
              , obj4 = { foo: [ 88 ],  truc:[ 123 ]} 
              , obj5 = { baz: [ 116, 17] } 
                ;
              function mergeByKey(...objN )
                {
                let o_names = objN.reduce((list,objArg,indx) => // objArg is obj1, obj2, objN
                  {
                  Object.keys(objArg).forEach( k => // make a list of object name [ objIndexs...] 
                    {                         // ob [ objIndexs...] on function argument
                    if (!list[k]) list[k] = []
                    list[k].push(indx)
                    })  
                  return list
                  },{})
                let res = {}
                for (let o_name in o_names )
                  res[o_name] = o_names[o_name].reduce((a,c)=>[...a,...objN[c][o_name]],[] )
                return res
                }
              
              console.log( mergeByKey( obj1, obj2, obj3, obj4, obj5 ))
              // or just - console.log( mergeByKey( obj1, obj2 ))
              .as-console-wrapper {max-height: 100%!important;top:0}

              【讨论】:

                【解决方案7】:

                我已经解决了你在函数之外的挑战,但它可以工作,而且如果你愿意,很容易在函数中实现它,结果如你所愿:

                // first create an array with all the keys from both objects
                let keys = Object.keys(obj1).concat(Object.keys(obj2));
                
                // Then remove/filter the duplicates keys
                let uniqueKeys = keys.filter((c, index) => {
                    return keys.indexOf(c) === index;
                });
                
                //at last do the merge. us if statment to avoid concatenating undefiend elements
                
                const obj3={};
                for(let key of uniqueKeys){
                  if ( Object.keys(obj1).includes(key) && Object.keys(obj2).includes(key)){
                      obj3[key]= obj1[key].concat( obj2[key]);
                      } else if (Object.keys(obj1).includes(key))
                        {
                           obj3[key]= obj1[key];
                        }
                          else{
                            obj3[key]= obj2[key];
                          }
                
                 
                   
                }
                 
                console.log(obj3);
                
                     ```
                
                
                  [1]: https://i.stack.imgur.com/w0RbI.png
                

                【讨论】:

                  猜你喜欢
                  • 2015-06-08
                  • 1970-01-01
                  • 1970-01-01
                  • 2019-09-26
                  • 1970-01-01
                  • 2015-12-05
                  • 1970-01-01
                  • 2019-12-02
                  • 1970-01-01
                  相关资源
                  最近更新 更多