-5

    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

Slim Shady
  • 1,045
  • 2
  • 12
  • 38
  • @trincot all the objects with "imgood" should exists. Desired Output ``` a: "imgood", b: { a1: { a2: "im good", b2: "imgood" }, b1: "imgood" } ``` – Slim Shady Jul 23 '17 at 21:22
  • you may add the wanted result to the question. – Nina Scholz Jul 23 '17 at 21:41
  • [What is the most efficient way to deep clone an object in JavaScript?](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript/122704#122704) and [How do I correctly clone an object in Javascript](https://stackoverflow.com/questions/728360/how-do-i-correctly-clone-a-javascript-object/728694#728694) – jfriend00 Jul 24 '17 at 01:53

4 Answers4

2

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; }
trincot
  • 317,000
  • 35
  • 244
  • 286
1

You could use an iterative and recursive approach for assigning the value.

This proposal iterates the source object and create new target properties if necessary and assign the value if no nested object is found.

function update(target, source) {
    Object.keys(source).forEach(function(key) {
        if (source[key] && typeof source[key] === 'object') {
            return update(target[key] = target[key] || (Array.isArray(source[key]) ? [] : {}), source[key]);
        }
        target[key] = source[key];
    });
}

var obj1 = { a: "imgood", b: { a1: { a2: "i shouldnt be here", b2: "imgood" }, b1: "imgood" } },
    obj2 = { b: { a1: { a2: "imgood" } } };

update(obj1, obj2);
console.log(obj1);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Pass obj1.b.a1 and obj2.b.a1 to Object.assign()

var obj1 = {
      a: "imgood",
      b: {
        a1: {
          a2: "i shouldnt be here",
          b2: "imgood"
        },
        b1: "imgood"
      }
    };
    
    var obj2 = {
      b: {
        a1: {
          a2: "imgood"
        }
      }
    };


Object.assign(obj1.b.a1, obj2.b.a1);

console.log(obj1);
guest271314
  • 1
  • 15
  • 104
  • 177
0

Your objects has the similar structure, so you can do the trick via a very simple function:

var obj1 = {
  a: "imgood",
  b: {
    a1: {
      a2: "i shouldnt be here",
      b2: "imgood"
    },
    b1: "imgood"
  }
};
    
var obj2 = {
  b: {
    a1: {
      a2: "imgood"
    }
  }
};

function changeA2 (obj) {
  obj['b']['a1']['a2'] = 'CHANGED';
  return obj;
}

console.log("new obj1: ", changeA2(obj1));
console.log("new obj2: ", changeA2(obj2));
P.S.
  • 15,970
  • 14
  • 62
  • 86