I need to combine two arrays of objects:
const local: [
{id: 1, balance: 2200, ref: 'A'},
{id: 2, balance: 2100, ref: 'C'}
]
const remote: [
{id: 1, balance: 3300, ref: 'B'},
]
I need to merge these arrays, such any two objects with the same id are merged - keeping the same ID, keeping the balance from remote
and combining their ref
values, so the ideal output of this example would be:
[
{ id: 1, balance: 3300, text: 'A / B' },
{ id: 2, balance: 2100, text: 'C' }
]
How would I do this? Ive tried the following:
function mergeFunc(remoteArray, localArray) {
const newArray = [];
//loop over one of the arrays
for (const localObj of localArray) {
//for each iteration, search for object with matching id in other array
if(remoteArray.some(remoteObj => remoteObj.id === localObj.id)){
//if found matching id, fetch this other object
const id:matchingRemoteObj = remoteArray.find(item => item.id === localObj.id);
//create new, merged, object
const newObj = {id:matchingRemoteObj.id, balance: id:matchingRemoteObj.balance, text:`${localObj.text} / ${id:matchingRemoteObj.text}`}
//push new value to array
newArray.push(newObj);
}
}
return newArray;
}
The issue is, this solution gives me an array of merged objects that had matching ID's. I need an array with all objects, only merging the ones with matching id's...
CodePudding user response:
The reason is below code,you just push match records,which cause this issue
if(remoteArray.some(remoteObj => remoteObj.id === localObj.id))
Below is a reference for you by using Array.map()
and Array.find()
const local = [
{id: 1, balance: 2200, ref: 'A'},
{id: 2, balance: 2100, ref: 'C'}
]
const remote = [
{id: 1, balance: 3300, ref: 'B'},
]
let result = local.map(e =>{
let r = remote.find(i => i.id === e.id)
let ref = r?.ref
if(ref){
e.balance = r.balance
e.ref = ' / ' ref
}
return e
})
console.log(result)
Update: If you want to make your original code works,you need to add else
block if there is no match
const local = [
{id: 1, balance: 2200, ref: 'A'},
{id: 2, balance: 2100, ref: 'C'}
]
const remote = [
{id: 1, balance: 3300, ref: 'B'},
]
function mergeFunc(remoteArray, localArray) {
const newArray = [];
//loop over one of the arrays
for (const localObj of localArray) {
//for each time, search for object with matching id in other array
if(remoteArray.some(remoteObj => remoteObj.id === localObj.id)){
//if found matching id, fetch this other object
const matchingRemoteObj = remoteArray.find(item => item.id === localObj.id);
//create new, merged, object
const newObj = {id:matchingRemoteObj.id, balance: matchingRemoteObj.balance, text:`${localObj.ref} / ${matchingRemoteObj.ref}`}
//push new value to array
newArray.push(newObj);
}else{
// this will add not match record into result array
newArray.push(localObj)
}
}
return newArray;
}
let result = mergeFunc(remote,local)
console.log(result)
CodePudding user response:
You can make use of array.map
and array.find
method,
To replace the balance of the match with the remote array you can use,
obj.balance = o.balance
To merge the ref string of matching id, you can use,
obj.ref = `${obj.ref} / ${o.ref}`
Working Snippet:
const local = [
{ id: 1, balance: 2200, ref: "A" },
{ id: 2, balance: 2100, ref: "C" },
];
const remote = [{ id: 1, balance: 3300, ref: "B" }];
const result = local.map((obj) => {
remote.find((o) => {
if (o.id === obj.id) {
obj.balance = o.balance;
obj.ref = `${obj.ref} / ${o.ref}`;
}
});
return obj;
});
console.log(result);