0

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!

1
  • 1
    what is your expected result? Commented May 31, 2021 at 11:45

3 Answers 3

1

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);

Sign up to request clarification or add additional context in comments.

4 Comments

What if I have a new array that doesn't match the existing data and I only want to insert it? how can I achieve it?
Do you want to add the element at the sorting order. or at the end
The sorting isn't important though :)) But correct me if I'm wrong, so basically, I'll just add else after the isExist block to add it if it's not yet exists. Am I correct?
Check it out @JokerBench
1
existingData.forEach(existingItem => {
 let item = updatedDate.find(u => u.id === existingItem.id);
 if(item){
    existingItem.product = item.product;
    existingItem.price= item.price;
  }
});

Comments

1

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));

1 Comment

HI @AKX but what if the incoming data has no matching existing data by id, then what I need also is that it will add automatically to the existing data array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.