Home > other >  javascript Object.assign() without overriding fields
javascript Object.assign() without overriding fields

Time:06-27

Is there any way to merge two objects, like Object.assign(a, b), but I want the same field in a keeps its origin value (without overriding from b).

a = {x: 1, y: 2}
b = {y: 3, z: 4}

Object.assign(a, b)
// Now we get a = {x: 1, y: 3, z: 4}, so what if I want {x: 1, y: 2, z: 4}?
console.log(a) 

CodePudding user response:

The best solution to this is to avoid using Object.assign and use spread operator as by doing so you'll achieve your goal with simple logic. In spread operator, the rightmost element overwrites the left one.

a = {x: 1, y: 2};
b = {y: 3, z: 4};
        
result = {...b, ...a}; 
result2 = {...a, ...b};

console.log(result); // {x: 1, y: 2, z: 4} 
console.log(result2); // {x: 1, y: 3, z: 4} 

CodePudding user response:

let a = { x: 1, y: 2 };
let temp = { ...a };
let b = { y: 3, z: 4 };

Object.assign(a, b);
Object.assign(a, temp);

console.log(a);

CodePudding user response:

You could use Object.entries and filter out keys that are already in a.

eg.

a = {x: 1, y: 2}
b = {y: 3, z: 4}

//Object.assign(a, b)
// Now we get a = {x: 1, y: 3, z: 4}, so what if I want {x: 1, y: 2, z: 4}?
Object.assign(a, Object.fromEntries(
  Object.entries(b).
    filter(([k])=>!(k in a))));

console.log(a) 

CodePudding user response:

To modify the a reference (like you seem to be wanting to do from your example), you could do:

const a = {x: 1, y: 2};
const b = {y: 3, z: 4};

Object.assign(a, {...b, ...a});
console.log(a);

This essentially says, replace the overlapping properties in b with those from a, and then merge this replaced object into a.

Above, the {...b, ...a} first merges a with b, so a overwrites properties in b, giving us:

{y: 3, z: 4, x: 1, y: 2}
// evalutes to
{z: 4, x: 1, y: 2}

Now we merge this result into a with the Object.assign() call:

{x: 1, y: 2, z: 4, x: 1, y: 2}
// evalutes to
{z: 4, x: 1, y: 2}
// ie:
{x: 1, y: 2, z: 4}
  • Related