I have two arrays A, B with objects from the database. I want to merge the objects from array B into array A that have a relation: (A[n].id == B[n].a_id).
const array_a = [
{
"id": 4,
"status": 0,
},
{
"id": 5,
"status": 1,
}
];
const array_b = [{
active: 1,
a_id: 5, // SELECTOR FOR MERGE
created_at: '2022-11-05 20:29:29',
firstname: 'user3',
lastname: ''
}];
Expected result:
const result = [
{
"id": 4,
"status": 0,
},
{
"id": 5,
"status": 1,
"active": 1,
"user_id": 5,
"created_at": '2022-11-05 20:29:29',
"firstname": 'user3',
"lastname:" ''
}
];
I tried this approach from another SO answer and got nowhere.
https://stackoverflow.com/a/53462680/18066399 :-/
CodePudding user response:
First, make a dictionary to look up later as dict ={}
where the key is a_id
and the value is the whole object itself. then iterate through the second array and look for if there is something already in dict
if it's then we need to get them by dict[val.id]
and merge the values with the original object.
Learn about map()
and reduce()
Trick:
As you said data come from a database so data can be bigger in size, So you may want to avoid loop nesting like inside .map()
again another loop like filter
find
etc. Suppose your database returns 1000 items
per each so if you use nested algorithms in the worst case you need to perform 1000*1000 = 1000000
steps which is slower :(
const array_a = [
{
"id": 4,
"status": 0,
},
{
"id": 5,
"status": 1,
}
];
const array_b = [{
active: 1,
a_id: 5, // SELECTOR FOR MERGE
created_at: '2022-11-05 20:29:29',
firstname: 'user3',
lastname: ''
}];
const dict = array_b.reduce((acc, val) => ({...acc, [val.a_id]: val}), {});
const res = array_a.map(val=> {
if(!dict[val.id]) return val; //If nothing in "dict" object by id we return original obj
const mergedObj = {...val, ...dict[val.id]}; //Merge two objects
delete Object.assign(mergedObj, {user_id: mergedObj.a_id})['a_id']; //create "user_id" by the value of "a_id" and delete old key "a_id"
return mergedObj;
});
console.log(res);
CodePudding user response:
const array_a = [
{
"id": 4,
"status": 0,
},
{
"id": 5,
"status": 1,
}
];
const array_b = [{
active: 1,
a_id: 5, // SELECTOR FOR MERGE
created_at: '2022-11-05 20:29:29',
firstname: 'user3',
lastname: ''
}];
const merged = array_a.map((item) => {
const found = array_b.find((i) => i.a_id === item.id);
return found ? { ...item, ...found } : item;
});
console.log("merged",merged);
A simple way of doing it: while looping inside the array_a, we check if the id is available in array_b as a_id, and if it was, we merge the data.
CodePudding user response:
A simple way to do this would be to use map()
and filter()
. I don't know how big your result arrays from the database are. Of course, my way may not be the most efficient. But then neither would the others. Maybe you could already solve the problem with your database structure!
const array_a = [
{
"id": 4,
"status": 0,
},
{
"id": 5,
"status": 1,
}
];
const array_b = [{
active: 1,
a_id: 5, // SELECTOR FOR MERGE
created_at: '2022-11-05 20:29:29',
firstname: 'user3',
lastname: ''
}];
const result = array_a.map(_a => {
const n = array_b.filter(_b => _b._id == _a.id);
return n.length ? {..._a, ...n[0]} : _a;
})
console.log(result)
Update with shorter solution
Inspired by this answer, which I personally found good. https://stackoverflow.com/a/61670621/18066399
const array_a = [
{
"id": 4,
"status": 0,
},
{
"id": 5,
"status": 1,
}
];
const array_b = [{
active: 1,
a_id: 5, // SELECTOR FOR MERGE
created_at: '2022-11-05 20:29:29',
firstname: 'user3',
lastname: ''
}];
const result = array_a.map(_a => ({..._a, ...array_b.find(_b => _b.a_id === _a.id)}));
console.log(result)