Joker Bench
Joker Bench

Reputation: 228

Replace/Update The Existing Array of Object that Matches the Incoming Array

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

Answers (3)

DecPK
DecPK

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

AKX
AKX

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

Rajdeep D
Rajdeep D

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

Related Questions