4
const obj1 = {
    prop1: 'value1',
    prop2: 'value2',
    prop3: { prop4: 'value4', prop5: {
         prop5: 'value5'
         } 
    },
}
const obj2 = {
    prop6: 'value6',
    prop2: 'value2',
    prop7: { prop8: 'value8', prop9: {
         prop10: 'value10'
         } 
    },
}

I have these two very nested objects in javascript, and I want to merge them into just one object. Some object property is identical, but some are not; I want to merge them, so the identical ones stay. how do I merge these two deeply nested objects?

1
  • Your question is not clear. What kind of output do you expect from the merge? How deeply do you want to merge? In the example you gave, there are no overlapping properties in the two objects, so a simple shallow merge should work. Commented Oct 27, 2023 at 21:07

4 Answers 4

4

Regarding merging, we generally have two approaches, Shallow merge and Deep Merge. For shallow merge, javascript has these ways.

  1. Object.assign()
  2. Merging via spread operator

But if you want to deep merge, you should iterate through all items of an object and merge them one by one (Merging Recursively) or use some great library like Lodash

  1. Sample of Deep Merging with Lodash
  2. How to Deep Merge JavaScript Objects?
Sign up to request clarification or add additional context in comments.

Comments

3

If anyone wish to merge two Object into just one object without using any Library like Lodash then you can do it as like below

function deepMergeObjects(obj1, obj2) {
    const result = {};

    for (const key in obj2) {
        if (obj2.hasOwnProperty(key)) {
            if (typeof obj2[key] === "object" && obj1.hasOwnProperty(key) && typeof obj1[key] === "object") {
                result[key] = deepMergeObjects(obj1[key], obj2[key]);
            } else {
                result[key] = obj2[key];
            }
        }
    }

    for (const key in obj1) {
        if (obj1.hasOwnProperty(key) && !result.hasOwnProperty(key)) {
            if (typeof obj1[key] === "object") {
                result[key] = deepMergeObjects(obj1[key], {});
            } else {
                result[key] = obj1[key];
            }
        }
    }

    return result;
}


const obj1 = {
    a: 1,
    b: {
        c: 2,
        d: 3,
    },
    test1: null,
    test2: {},
    test3: {},
    test4: false,
    test5: undefined
};

const obj2 = {
    b: {
        d: 4,
        e: 5,
    },
    f: 6,
    test1: {},
    test2: null,
    test3: false,
    test4: {},
    test5: {}
};

console.time("time");
const mergedObject = deepMergeObjects(obj1, obj2);
console.timeEnd("time");
console.log(JSON.stringify(mergedObject));


additionally If anyone need to override or add the values of obj1 into obj2 then you can do it as like below way

Method 1:- override or add the values of obj1 into obj2 using ForLoop

function deepMergeObjects(obj1, obj2) {
    for (const key in obj1) {
        if (obj1.hasOwnProperty(key)) {
            if (typeof obj1[key] === "object") {
                if (typeof obj2[key] !== "object" || Array.isArray(obj2[key])) {
                    obj2[key] = Array.isArray(obj1[key]) ? [] : {};
                }
                deepMergeObjects(obj1[key], obj2[key]);
            } else {
                obj2[key] = obj1[key];
            }
        }
    }
}

const obj1 = {
    a: 1,
    b: {
        c: 2,
        d: 3,
    },
    test1: null,
    test2: {},
    test3: {},
    test4: false,
    test5: undefined
};

const obj2 = {
    b: {
        d: 4,
        e: 5,
    },
    f: 6,
    test1: {},
    test2: null,
    test3: false,
    test4: {},
    test5: {}
};

console.time("time");
deepMergeObjects(obj1, obj2);
console.timeEnd("time");
console.log(JSON.stringify(obj2));

Method 2:- override or add the values of obj1 into obj2 using recursively Set Object

const deepMerge = (a, b, fn) =>
  [...new Set([...Object.keys(a), ...Object.keys(b)])].reduce((acc, key) => {
    if (a.hasOwnProperty(key) && b.hasOwnProperty(key)) {
      if (a[key] === null || a[key] === undefined) {
        acc[key] = b[key];
      } else if (b[key] === null || b[key] === undefined) {
        acc[key] = a[key];
      } else if (typeof a[key] === "object" && typeof b[key] === "object") {
        acc[key] = deepMerge(a[key], b[key], fn);
      } else {
        acc[key] = fn(key, a[key], b[key]);
      }
    } else if (a.hasOwnProperty(key)) {
      acc[key] = a[key];
    } else {
      acc[key] = b[key];
    }
    return acc;
  }, {});


const obj1 = {
    a: 1,
    b: {
        c: 2,
        d: 3,
    },
    test1: null,
    test2: {},
    test3: {},
    test4: false,
    test5: undefined
};

const obj2 = {
    b: {
        d: 4,
        e: 5,
    },
    f: 6,
    test1: {},
    test2: null,
    test3: false,
    test4: {},
    test5: {}
};

console.time("time");
const mergedObject = deepMerge(obj1, obj2, (key, a, b) => {
  if (typeof a === "object") {
    return Array.isArray(a) ? [] : {};
  } else {
    return b;
  }
});
console.timeEnd("time");

console.log(JSON.stringify(mergedObject));

I hope this one helps to You

Happy Coding :)

Comments

0

In Deno you can use deepMerge -

Merges the two given Records, recursively merging any nested Records with the second collection overriding the first in case of conflict

import { deepMerge } from "https://deno.land/std/collections/mod.ts"

const o3 = deepMerge(o1, o2)

Comments

-1

Recursive merge for array and object

const obj1 = {
  prop1: 'value1',
  prop2: 'value2',
  prop3: {
    prop4: 'value4',
    prop5: {
      prop5: 'value5'
    },
    a: ['a', 'b']
  },
}

const obj2 = {
  prop6: 'value6',
  prop2: 'value2',
  prop7: {
    prop8: 'value8',
    prop9: {
      prop10: 'value10'
    }
  },
  prop3: {
    prop9: 'value9',
    prop8: {
      prop7: 'value7',
      prop8: {
        prop7: 'value7'
      }
    },
    a: ['a', 'b']
  },
}


const Merge = (object1, object2) => {
  if (Array.isArray(object2)) {
    return [...object1, ...object2]
  } else {
    return Object.entries(object2).reduce((acc, [key, value]) => {
      if (
        Object.keys(acc).includes(key) &&
        typeof value === 'object'
      ) {
        acc[key] = Merge(acc[key], value)
      } else {
        acc[key] = value
      }
      
      return acc
    }, { ...object1 })
  }
}

const result = Merge(obj1, obj2)

console.log(result)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.