Merging 2 objects into a new one, with selective condition

Viewed 55

I'm trying to create a new group of objects adding a new component to the first one from the second one, based on a condition. Here is an example:

Have this 2 group of objects:

const one = [{code: 'a'},{ code: 'b'}, {code: 'c'}]
const two = [{code: 'b', status: 'active'}]

and would like to have a result like:

{ code: 'a', status: 'empty' }
{ code: 'b', status: 'active' }
{ code: 'c', status: 'empty' }

This is the code I wrote as example:

const one = [{code: 'a'},{ code: 'b'}, {code: 'c'}]
const two = [{code: 'b', status: 'active'}]



var final = []
var temp = {}

for(let holiday of one) {
    // here I started to create a temp object with components of object one
    temp.code = holiday.code
    
    // here I check if same code from object one exist in any object two
    var checksub= two.find(o => o.code == holiday.code)

    // then assigns proper value to temp object from object two, of a default instead
    if(checksub){temp.status = checksub.status}
    else {temp.status = 'empty'}

    // then push the object into new array of objects
    final.push(temp)
}
    
console.log(final)

But the result I'm getting is:

[
  { code: 'c', status: 'empty' },
  { code: 'c', status: 'empty' },
  { code: 'c', status: 'empty' }
]

Why I'm getting 3 times the last object? I've tried different methods (using forEach and for loops) and always get same weird result.... what am I doing wrong? Thanks!!!

2 Answers

You are passing the object via reference so if you change the value of object on one place, all the places where that value is used will be updated. Since in each loop, the value of temp is changed, your array is updated with the updated value. So if you just pass the clone of the temp object then all your values would not be affected.

const one = [{code: 'a'},{ code: 'b'}, {code: 'c'}]
const two = [{code: 'b', status: 'active'}]



var final = []
var temp = {}

for(let holiday of one) {
    // here I started to create a temp object with components of object one
    temp.code = holiday.code
    
    // here I check if same code from object one exist in any object two
    var checksub= two.find(o => o.code == holiday.code)

    // then assigns proper value to temp object from object two, of a default instead
    if(checksub){temp.status = checksub.status}
    else {temp.status = 'empty'}

    // then push the clone of object into new array of objects
    final.push({...temp})
}
    
console.log(final)

All you had to do is final.push({...temp}) which will destructure the temp object and pass it as a new object.

The final will be as follows:

[
 {code: "a", status: "empty"},
 {code: "b", status: "active"},
 {code: "c", status: "empty"},
]
const one = [{code: 'a'},{ code: 'b'}, {code: 'c'}]
const two = [{code: 'b', status: 'active'}]

const final = one.map((x) => {
    const twoContains = two.find(y => y.code === x.code);
    return {
        code: x.code,
        status: twoContains ? twoContains.status : 'empty'
    };
});

OR Simply (much shorter version)

const final = one.map(x => ({
    code: x.code,
    status: (two.find(y => y.code === x.code) || {status: 'empty'}).status
}));

console.log(final);

/* output
[
    { code: 'a', status: 'empty' },
    { code: 'b', status: 'active' },
    { code: 'c', status: 'empty' }
]    
*/

Its that simple

Related