Search code examples
javascriptobjectecmascript-6nested-loops

Nested Object Assign using Javascript


    var obj1 = {
      a: "imgood",
      b: {
        a1: {
          a2: "i shouldnt be here",
          b2: "imgood"
        },
        b1: "imgood"
      }
    };
    
    var obj2 = {
      b: {
        a1: {
          a2: "imgood"
        }
      }
    };
    console.log(Object.assign(obj1,obj2));

I want the a2 to be replaced but without loosing other properties.

in Simplest, Shortest and Fastest way possible


Solution

  • Here is a solution with a for loop in a recursive function:

    function recursiveAssign(a, b) {
        if (Object(b) !== b) return b;
        if (Object(a) !== a) a = {};
        for (let key in b) {
            a[key] = recursiveAssign(a[key], b[key]);
        }
        return a;
    }
    
    var obj1 = {
      a: "imgood",
      b: {
        a1: {
          a2: "i shouldnt be here",
          b2: "imgood"
        },
        b1: "imgood"
      }
    };
    
    var obj2 = {
      b: {
        a1: {
          a2: "imgood"
        }
      }
    };
    
    console.log(recursiveAssign(obj1, obj2));
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    Or in a functional manner:

    function recursiveAssign(a, b) {
        return Object(b) !== b ? b 
            : Object.keys(b).reduce ( (a, key) =>
                Object.assign(a, { [key]: recursiveAssign(a[key], b[key]) })
              , Object(a) === a ? a : {} );
    }
    
    var obj1 = {
      a: "imgood",
      b: {
        a1: {
          a2: "i shouldnt be here",
          b2: "imgood"
        },
        b1: "imgood"
      }
    };
    
    var obj2 = {
      b: {
        a1: {
          a2: "imgood"
        }
      }
    };
    
    console.log(recursiveAssign(obj1, obj2));
    .as-console-wrapper { max-height: 100% !important; top: 0; }