简体   繁体   中英

How to merge the arrays in two objects by key (Javascript)

I am trying to write a function that merges two objects by their key. The objects both have an array of numbers as their value pair and it is the arrays I want to merge.

The input for this function is

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]
}

I tried using concat and spread operator however the answer I get is missing the "5" from the second object's foo. Also, I noticed with my current approach, if a key/value pair exists only in obj2, it will not be copied. Is there a better approach to this problem? Here's my code, please help!

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 ] }

Not the most elegant solution, but it appears to work

 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))

You can take the distinct array of keys from both objects, then iterate that array and check for key in one object and not the other - therefore take that array, or if the key is in both objects, merge the arrays.

See below:

 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);

You could merge your two objects into one using the spread syntax ... , this will give you the keys from both objects when you use Object.keys() on the merged object. You can then use .reduce() on this array of keys to create a new object. For each key, you can grab the array from obj1 (if it doesn't exist, default it to an empty array using || [] ), concatenated with the array from obj2 (you can also default this if it doesn't exists to an empty array):

 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);

Try something like this (assuming you don't know the object keys and that the values are always arrays).

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;
}

you can do that...

 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((ac)=>[..,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}

 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 );

I have solved your challenge outside a function, but it works and it is easy to implement it in a function if you would like that, and the result is as you wanted:

// 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM