Reputation: 228
I'm trying to find and replace the array if an incoming arrays matches the existing one but unfortunately, I'm stucked with the some
Here's my existing array.
let existingData = [{
id: 1,
product: 'Soap',
price: '$2'
},{
id: 2,
product: 'Sofa',
price: '$30'
},{
id: 3,
product: 'Chair',
price: '$45'
}]
And here's my incoming array.
const updateData = [{
id: 1,
product: 'Soap',
price: '$3'
},{
id: 2,
product: 'Sofa',
price: '$35'
}]
So far, I saw the foreach
but unfortunately, I'm not sure how can I use it if the term is an array. But I get stuck and I can't proceed.
const updateData = [{
id: 1,
product: 'Soap',
price: '$3'
},{
id: 2,
product: 'Sofa',
price: '$35'
}]
existingData.forEach(d=>{
if(d.id === ??? how can I match this to the incoming array?)
// if matches, then update the existing data with the updated one.
})
And the expected result must be something like this:
let existingData = [{
id: 1,
product: 'Soap',
price: '$3'
},{
id: 2,
product: 'Sofa',
price: '$35'
},{
id: 3,
product: 'Chair',
price: '$45'
}]
If in some cases, the data is not present in the existingData, then the incoming array will just add simply in the existing array.
Please help how can I achieve it and if there's a better and cleaner way to do this, please let me know. Thank you!
Upvotes: 0
Views: 174
Reputation: 25408
You can easily achieve this result using forEach and find
let existingData = [{
id: 1,
product: "Soap",
price: "$2",
},
{
id: 2,
product: "Sofa",
price: "$30",
},
{
id: 3,
product: "Chair",
price: "$45",
},
];
const updateData = [{
id: 1,
product: "Soap",
price: "$3",
},
{
id: 2,
product: "Sofa",
price: "$35",
},
];
updateData.forEach((obj) => {
let isExist = existingData.find((o) => o.id === obj.id);
if (isExist) {
isExist.price = obj.price;
isExist.product = obj.product;
}
});
console.log(existingData);
If there are multiple properties that need to be updated then you can use for..in loop over the updated object and replace the prop in the existing property.
updateData.forEach((obj) => {
let isExist = existingData.find((o) => o.id === obj.id);
if (isExist) {
for (let prop in obj) {
isExist[prop] = obj[prop];
}
}
});
If you want to add the data if it doesn't exist in the existing array then you need to push it into existingData
array.
let existingData = [{
id: 1,
product: "Soap",
price: "$2",
},
{
id: 2,
product: "Sofa",
price: "$30",
},
{
id: 3,
product: "Chair",
price: "$45",
},
];
const updateData = [{
id: 1,
product: "Soap",
price: "$3",
},
{
id: 2,
product: "Sofa",
price: "$35",
},
{
id: 6,
product: "Sofa",
price: "$135",
},
];
updateData.forEach((obj) => {
let isExist = existingData.find((o) => o.id === obj.id);
if (isExist) {
for (let prop in obj) {
isExist[prop] = obj[prop];
}
} else {
existingData.push(obj);
}
});
console.log(existingData);
Upvotes: 1
Reputation: 169042
Given your existingData
and updateData
, you can quite simply do something like this:
// form a temporary object mapping updated objects' ids to the new ids
const updateDataByKeys = Object.fromEntries(updateData.map(e => [e.id, e]));
// map through `existingData`, replacing old entries with updated where they
// exist in the above temporary object, using the old object if they don't.
const newData = existingData.map(e => updateDataByKeys[e.id] || e);
Creating the temporary object should make this approach quite a bit faster than approaches using .find()
on updateData
.
If you need to merge the data from updateData
into the existing objects, you could do
const newData = existingData.map(
e => updateDataByKeys[e.id] ? ({...e, ...updateDataByKeys[e.id]}) : e
);
EDIT: Based on comments, if you also need to add new objects from updateData:
// form a temporary object mapping updated objects' ids to the new ids
const updateDataByKeys = Object.fromEntries(updateData.map(e => [e.id, e]));
// Map through `existingData`, replacing old entries with updated where they
// exist in the above temporary object, using the old object if they don't.
// When using an update object, removes it from the mapping; the left-over
// new data (which had no ID in the old data) are then concatenated to the
// list.
const newData = existingData.map(e => {
if(updateDataByKeys[e.id]) {
const val = updateDataByKeys[e.id];
delete updateDataByKeys[e.id];
return val;
}
return e;
}).concat(Object.values(updateDataByKeys));
Upvotes: 1
Reputation: 3910
existingData.forEach(existingItem => {
let item = updatedDate.find(u => u.id === existingItem.id);
if(item){
existingItem.product = item.product;
existingItem.price= item.price;
}
});
Upvotes: 1