Home > Back-end >  How do I combine two objects by merging the values of same properties?
How do I combine two objects by merging the values of same properties?

Time:03-08

Is there a way we can combine two objects by nesting the values if properties are same instead of overwriting ? Eg:

const obj1 = {a:10,b:13}
const obj2 = {a:84,c:70}

desired result : 
combinedObject = {a:{0:10,1:84}, b:13, c:70}

CodePudding user response:

const obj1 = { a: 10, b: 13 }
const obj2 = { a: 84, c: 70, d: 40 }

function foo(obj1, obj2) {

    const newObject = {}
    for (const key in { ...obj1, ...obj2 }) {
        const element1 = obj1[key];
        const element2 = obj2[key];
        if (element1 && element2)
            newObject[key] = [element1, element2]
        else if (element1)
            newObject[key] = element1
        else if (element2)
            newObject[key] = element2
    }
    return newObject
}
console.log(foo(obj1, obj2))

CodePudding user response:

Here is two solutions, The first one, merge the values of the keys into an object under the same key name. The second one, propose a way to merge them as you mention, but it is a bit more complicated to maintain the index of each key but it is still possible.

The result of both options looks like that

// Option 1
{ a: [ 10, 11, 84 ], b: [ 13, 12 ], c: 70, d: 50 }

// Option 2
{
  a: { '0': 10, '1': 11, '2': 84 },
  b: { '0': 13, '1': 12 },
  c: 70,
  d: 50
}

And here is how it is achieved

const obj1 = { a: { 0: 10, 1: 11 }, b: 13 }
const obj2 = { a: 84, b: 12, c: 70, d: 50 }
const allKeys = Object.keys({ ...obj1, ...obj2 });

const merged1 = {};
for (const key of allKeys) {
    const isObj1Object = typeof obj1[key] === 'object';
    const isObj2Object = typeof obj2[key] === 'object';
    if (obj1[key] && obj2[key]) {
        merged1[key] = [
            ...(isObj1Object ? Object.values(obj1[key]) : [obj1[key]]),
            ...(isObj2Object ? Object.values(obj2[key]) : [obj2[key]]),
        ];
    } else if (obj1[key] || obj2[key]) {
        merged1[key] = obj1[key] || obj2[key];
    }
}

console.log(merged1);

const merged2 = {};
for (const key of allKeys) {
    if (obj1[key] && obj2[key]) {
        const isObj1Object = typeof obj1[key] === 'object';
        const isObj2Object = typeof obj2[key] === 'object';
        merged2[key] = {
            ...(
                isObj1Object
                    ? Object.values(obj1[key]).reduce((acc, v, i) => {
                        acc[Object.keys(obj2[key]).length   i] = v;
                        return acc;
                    }, {})
                    : (
                        isObj2Object
                            ? { [Object.keys(obj2[key]).length]: obj1[key] }
                            : { 0: obj1[key] }
                    )
            ),
            ...(
                isObj2Object
                    ? Object.values(obj2[key]).reduce((acc, v, i) => {
                        acc[Object.keys(obj1[key]).length   i] = v;
                        return acc;
                    }, {})
                    : (
                        isObj1Object
                            ? { [Object.keys(obj1[key]).length]: obj2[key] }
                            : { 1: obj2[key] })
            ),
        };
    } else if (obj1[key] || obj2[key]) {
        merged2[key] = obj1[key] || obj2[key];
    }
}

console.log(merged2);

You can test the different options here playground

If you would like to have a deep merged without any level limitation you would have to update the code to use a recursive method.

CodePudding user response:

you must follow the rules of object definitions

const obj1 = {a:10,b:13}
const obj2 = {a:84,c:70}
//it can be like this
combinedObject = {a:[10,84], b:13, c:70}
// you can access to that value like this 
let value = combinedObject.a[0];

and finally, you can use this code for the combination

    const obj1 = { a: 10, b: 13 };
    const obj2 = { a: 84, c: 70 };
    const props = Object.getOwnPropertyNames(obj2);
    let combinedObject = { ...obj1 };
    for (let i = 0; i < props.length; i  ) {
      if (combinedObject[props[i]])
        combinedObject[props[i]] = [combinedObject[props[i]], obj2[props[i]]];
      else combinedObject[props[i]] = obj2[props[i]];
    }
    //result :{a:[10,84], b:13, c:70}

as you wish

const obj1 = { a: 10, b: 13 };
    const obj2 = { a: 84, c: 70 };
    const props = Object.getOwnPropertyNames(obj2);
    let combinedObject = { ...obj1 };
    for (let i = 0; i < props.length; i  ) {
      if (combinedObject[props[i]])
        combinedObject[props[i]] = {0:combinedObject[props[i]], 1:obj2[props[i]]};
      else combinedObject[props[i]] = obj2[props[i]];
    }
    console.log(combinedObject);
//result :{a:{0:10,1:84}, b:13, c:70}
  • Related