teestunna
teestunna

Reputation: 217

If two different objects have same key name, merge their value

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

Results in: obj1 = { names: ["Zack","Cody","John","Jake"]}

What I have tried:

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

Upvotes: 0

Views: 192

Answers (6)

Paul Rooney
Paul Rooney

Reputation: 21619

You can just iterate over each objects properties and add them to the new object if that property does not exist. To deal with merges where the same key exists in other objects we can define a merge strategy function that will resolve the conflict.

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

the function only allows one strategy per merge, which might be a bit limiting for more complex cases but for simple ones like this its ok.

Upvotes: 2

Praneet Dixit
Praneet Dixit

Reputation: 1425

In your code, you were comparing two arrays - Object.keys(obj1) and Object.keys(obj2). This condition would never be true because no two arrays are equal because they have reference to different memory location.

To deal with this, you can compare their contents. This is what I am doing in the below snippet -

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

I am only comparing the first keys in both objects in the above snippet. If you like to do this for every key in both objects, then you can use a loop with indexes replacing the [0].

Note - If you are going to use the above approach, then the order of keys in both objects matters.

Upvotes: 1

kmoser
kmoser

Reputation: 9283

Iterate through the keys in obj1, and for every one that exists in obj2, merge its values into 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
    }
});

Upvotes: 2

Hao Wu
Hao Wu

Reputation: 20867

Here's one-liner using Object.entries, Object.fromEntries and Array#map, assuming the properties share the same key name are always arrays:

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

Upvotes: 1

Hải Bùi
Hải Bùi

Reputation: 2931

You can try lodash.merge, powerful function to merge multiple objects

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

Upvotes: 1

hgb123
hgb123

Reputation: 14891

You could concat the value by wrapping into array element and flatten (or concat as @ggorlen suggested in the comment) it

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

Upvotes: 1

Related Questions