Replace or update the current array of objects that align with the incoming array

I've been struggling to figure out how to find and replace an array that matches the existing one. The issue lies with using the some method.

Here is the current array:

let existingData = [{
    id: 1,
    product: 'Soap',
    price: '$2'
},{
    id: 2,
    product: 'Sofa',
    price: '$30'
},{
    id: 3,
    product: 'Chair',
    price: '$45'
}]

And here is the incoming array:

const updateData = [{
    id: 1,
    product: 'Soap',
    price: '$3'
},{
    id: 2,
    product: 'Sofa',
    price: '$35'
}]

I have considered using the forEach method, but I'm unsure of how to handle it when dealing with arrays. This has resulted in me getting stuck and unable to move forward.

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 there is a match, update the existing data with the updated one.
})

The expected result should resemble this:

let existingData = [{
    id: 1,
    product: 'Soap',
    price: '$3'
},{
    id: 2,
    product: 'Sofa',
    price: '$35'
},{
    id: 3,
    product: 'Chair',
    price: '$45'
}]

If, in certain cases, the data is not found in existingData, then simply add the incoming array to the existing array.

I would appreciate any guidance on how to achieve this or if there is a more efficient solution available. Thank you!

Answer №1

To achieve the desired outcome, you can make use of forEach along with 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 require updating, you can utilize a for..in loop to iterate over the updated object and replace the corresponding property in the existing data.

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 wish to add new data items that do not currently exist in the existing array, you can simply push them into the 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);

Answer №2

Iterating through the existingData array, each existingItem is checked against the updatedDate array to find a matching item by id. If a match is found, the product and price properties of the existingItem are updated with those from the matching item in the updatedDate array.

Answer №3

To update your data based on the existingData and updateData, you can follow this simple process:

// Create a temporary object that maps updated objects' ids to their new ids
const updateDataByKeys = Object.fromEntries(updateData.map(e => [e.id, e]));

// Iterate through `existingData`, replacing old entries with the updated ones where they exist in the temporary object,
// otherwise retain the old object.
const newData = existingData.map(e => updateDataByKeys[e.id] || e);

Building the temporary object will yield better performance compared to using .find() on updateData.

If you want to merge the data from updateData into the existing objects as well, you can do the following:

const newData = existingData.map(
  e => updateDataByKeys[e.id] ? ({...e, ...updateDataByKeys[e.id]}) : e
);

UPDATE: As per feedback, if you also need to incorporate new objects from updateData:


// Create a temporary object that maps updated objects' ids to the new ids
const updateDataByKeys = Object.fromEntries(updateData.map(e => [e.id, e]));

// Iterate through `existingData`, replacing old entries with updated ones where they
// match in the temporary object. Remove the updated objects from the mapping;
// then concatenate any remaining new data (that were not present in the old data) 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));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

JavaScript filename

This question may appear simple, but I believe the answer is not as straightforward. Here it goes: Should I keep the filename of jQuery as "jquery-1.3.2.min.js" for compatibility reasons, or should I rename it to jquery.js? In my opinion, it's best ...

I encounter obstacles when trying to execute various tasks through npm, such as downloading packages

Currently, I am facing an issue while trying to set up backend development using node.js on my personal computer. The problem lies with the npm command as it is not functioning correctly. Despite successfully installing a file without any errors, I am unab ...

Can I receive a PHP echo/response in Ajax without using the post method in Ajax?

Is it feasible to use Ajax for posting a form containing text and images through an HTML form, and receiving the response back via Ajax? Steps 1.) Include the form in HTML with a submit button. 2.) Submit the form to PHP, where it will process and upload ...

Display only a loading image with a see-through background after submitting the page

After submitting the page, I would like to display a loading image in the middle of the page with a transparent background. The current styling code I have used is as follows: #loading { position: fixed; top: 50%; left: 50%; z-index: 1104; ...

Comparing two jQuery methods for looping through Ajax requests - which one is the best option?

Currently working on a blog project that involves integrating Isotope Jquery (for layout/filtering/sorting), Infinite Scroll, and dynamic loading of all blog excerpts via Ajax. The goal is to apply filtering and sorting to all excerpts before they are load ...

Unable to display information retrieved from an API within a React application

I am facing an issue with rendering questions fetched from an API. I have set up the state and used useEffect to make the API call. However, when I try to display the questions, it seems to disrupt my CSS and show a blank page. I even attempted moving the ...

The useEffect function is executing two times

Check out this code snippet: import { type AppType } from 'next/app' import { api } from '~/utils/api' import '~/styles/globals.css' import Nav from '~/components/Nav' import { useEffect, useState } from 'react& ...

Using JavaScript to dynamically change the IDs of multiple select elements during runtime

I am facing an issue when trying to assign different IDs to multiple select elements at runtime. The number of select elements may vary, but I need each one to have a unique ID. Can anyone assist me in locating the select elements at runtime and assignin ...

Generating a new root in React 18 results in numerous rounds of rendering and execution

Every time I attempt to run this code in React 18, it seems to render multiple times unlike React 17 where it only executes once and functions properly. How can I modify the code so that it only runs once? Is there a specific reason for the multiple execu ...

Eradicating Pinpointers on Navigation Tool (Google Maps)

I have a feature that utilizes an ajax request to generate a marker or multiple markers when the user interacts with the map. Once a marker is created at a specific location by the user, I then set up a click event on the marker itself. The issue arises w ...

What is the best way to display an array of values using a foreach loop in PHP?

Seeking help in automating my navigation links. Is there a way to use foreach to automatically display them and avoid the 'undefined offset' error? Also, how can I skip the first item in the array (i.e. title)? 'control' => array( ...

The jQuery AJAX delete function is only able to capture the initial form submission

I am facing an issue with making an AJAX call to a PHP file to delete a row in the database. The problem is that it only deletes the first row. Despite my extensive research on this matter, I have not been able to find a solution. Therefore, I am reaching ...

The arrival of chat featuring Ajax, long-polling, and support for multiple users has finally

Imagine a site with three modules: "links", "home", and "chat". The "links" and "home" modules are static pages that do not require long polling. However, in the "chat" module, new messages may arrive at any time from other users, requiring an immediate up ...

The React-loadable alert indicated a discrepancy in the text content

Utilizing react-loadable for dynamic JS module loading is part of my process. With server-side rendering already set up and functioning correctly for react-loadable, I am encountering an issue on the client side. Upon page load, a warning message appears i ...

What is the reason behind this being deemed as true?

Imagine we have this snippet of code: var attachRed = false; Why is attachRed = !attachRed equivalent to true? I'm curious because I'm working with Vue.js and trying to grasp why this particular piece of code functions as it does. <div id= ...

What is the process for transmitting images from React Native to native modules?

Challenge I am facing an issue trying to send an array of locally saved images from the JavaScript side (stored in an assets folder) to both iOS and Android native sides. The native code processes the images and returns a new image successfully when using ...

Tips for concealing subsequent pages and displaying pagination in jQuery ajax response

Is there a way to display pagination based on a limiter in an ajax response? For example, if the limiter is set to 5, only show 10 page links and hide the rest. 1 2 3 4 5 6 7 8 9 10 .. next 11 12 13 14 15.. next I attempted to count the li elements in ...

IE browser transparency effect on canvas

I have encountered an issue when drawing a shape on canvas using kineticJS and setting the fill to none. The code snippet I am using is below: var rect = new Kinetic.Path({ x: 0, y: 0, data: 'm 2.0012417,2.0057235 ...

How can Vue define the relationship on the client-side when submitting a post belonging to the current user?

Currently, I am developing an application using Node.js, specifically Express server-side and Vue client-side, with SQLite + Sequelize for managing the database. One of the features of this app is that a user can create a post. While this functionality ex ...

Learn how to trigger the keydown function in VUE programming

I am trying to create a method that will be triggered whenever any key on the keyboard is pressed, regardless of where the focus is. I want to be able to determine which key was pressed in this method. Currently, I have set up an event listener for keydow ...