Efficiently and Effectively Comparing Two Arrays of Objects in JavaScript

Let's imagine we have 2 sets of data arrays, A (original) and B (updated).

var A = [ 
      { id: 1, value: 'Product Name 1' },
      { id: 2, value: 'Product Name 2' },
      { id: 3, value: 'Product Name 3' },
      { id: 4, value: 'Product Name 4' },
      { id: 5, value: 'Product Name 5' } 
]


var B = [ 
      { id: 1, value: 'Product Name 1' },
      { id: 2, value: 'Changed Name' },
      { value: 'New Product' }
]

The goal is to compare both arrays, identifying differences such as deleted items from array A that are not present in array B, edited items with changed 'value' property, and new items added without an id.

A logic for comparison can be summarized as follows (assuming each A and B are one element from their respective arrays)

If A.id == B.id and A.value !== B.value then it's an Edit
  
If B.id doesn't exist in A then it's a New item

If B.id is not found in A then it's Deleted

We need to create arrays for Added, Edited, and Deleted elements.

The expected result arrays would look like this:

Added = [ 
      { value: 'New Product'} 
]

Edited = [ 
      { id: 2, value: 'Changed Name' }
]

Deleted = [
      { id: 3, value: 'Product Name 3' },
      { id: 4, value: 'Product Name 4' },
      { id: 5, value: 'Product Name 5' } 
]

Answer №1

To achieve this, you can utilize the filter method along with some. Here is an example implementation:

var arr1 = [
    { id: 1, value: 'Product Name 1' },
    { id: 2, value: 'Product Name 2' },
    { id: 3, value: 'Product Name 3' },
    { id: 4, value: 'Product Name 4' },
    { id: 5, value: 'Product Name 5' }
]

var arr2 = [
    { id: 1, value: 'Product Name 1' },
    { id: 2, value: 'Changed Name' },
    { value: 'New Product' }
]

var deletedItems = arr1.filter(function (item) {
    return !arr2.some(function (otherItem) { return otherItem.id === item.id })
})

var changedItems = arr1.filter(function (item) {
    return arr2.some(function (otherItem) { return (otherItem.id === item.id) && (otherItem.value !== item.value) })
})

var addedItems = arr2.filter(function (item) {
    return !arr1.some(function (otherItem) { return item.id === otherItem.id })
})

console.log(deletedItems);
console.log(changedItems);
console.log(addedItems);

If you want to retrieve B's elements in the changedItems array, simply swap the positions of arr1 and arr2 in that specific part of the code.

Answer №2

If you're looking for a solution, here's an example using the utility library called lodash:

let newArray = _.cloneDeep(originalArray);
let removeArray = _.cloneDeep(arrayToRemove);
let modifiedArray = _.remove(newArray, function(item) {
    return _.some(removeArray, function(removeItem, index) {
        if (item.id === removeItem.id) {
            removeItem.splice(index, 1);
            return true;
        }
        return false;
    });
});

Answer №3

To implement this logic, you can utilize the following code snippet:

var finalResult = [];
for(var i in arrayA) {
    var elementA = arrayA[i], j;
    for(j in arrayB) {
        var elementB = arrayB[j];
        if(elementB.id == elementA.id ) {
            finalResult.push(elementB);
            break;
        }
    }
    if(j == arrayB.length-1) 
        finalResult.push(elementA);
}

Answer №4

.reduce() combined with .find() (ES6)

var finalResult = { new: [], edited: [], deleted: [] };

finalResult = B.reduce(function (l, r) {
    if (typeof r.id === "undefined") {
        l.new.push(r);
    } else {
        var elementInA = this.find(function (el) {
            return el.id === r.id;
        });

        if (typeof elementInA === "undefined") {
            l.deleted.push(r);
        } else if (elementInA.value !== r.value) {
            l.edited.push(r);
        }
    }

    return l;
}.bind(A), finalResult);    // .bind(A) is used to make the array <A> accessible as <this> in the reduce callback.
                           // Alternatively, A.find could also be used instead of this.find

console.log(finalResult);  // {"new":[{"value":"New Product"}],"edited":[{"id":2,"value":"Changed Name"}],"deleted":[]}

View fiddle

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

What is the best way to upgrade Angular from version 10 to 12?

Currently tackling an Angular project migration from version 10 to version 12. Unfortunately, the project seems to be encountering issues post-migration and is not running as expected. ...

Unable to retrieve information obtained from MongoDB

After successfully retrieving all data from the "topics" collection using find() with cursor and foreach, I am encountering an issue. When I attempt to assign the fetched information to a variable named "data" and send it back to the page, it consistently ...

Arranging arrays of objects based on their occurrence rate

I am working with an array of objects that looks like this: students = [ { "name": "Ana Barbique", "category":"B" } { "name": "Marko Polo", "category":"B" } { "name": "Nick Harper", "cate ...

Is there a way to retrieve the HTML raw code using backticks for string interpolation in JavaScript?

I am working on a resume builder project where the HTML template file is stored in Firebase storage and retrieved using a URL. The template has been modified to include string interpolation, such as <h1>${name}</h1>. However, when I fetch the d ...

"Want to learn how to dynamically disable an input field in AngularJS when another field is selected? Find out how to achieve this using the

Hey there, I'm dealing with two input fields. Input field A is a drop-down menu and input field B. They both have the same value (same ng-model). My goal is to clear the second input field whenever the user selects an option from the dropdown. Can any ...

Updating the material-ui checkbox state to reflect the checked, unchecked, or indeterminate status, can be achieved in reactjs without relying on state

I am currently using Material-UI checkbox components and I have a requirement to programmatically change the state of checkboxes to be checked, unchecked, or indeterminate based on the click of another checkbox. This action needs to be applied to a list of ...

How to convert an Excel file into a two-dimensional array in Java using Apache POI

I have been given an assignment to handle an Excel file that has a specific format, and my task is to read the file, sum up the units of matching product IDs, and display them in a similar column/row format. I apologize if my approach seems unrefined; I ...

Encountered an error while attempting to convert react-native-reanimated-65-jsc.aar

ERROR: App installation failed after 19 seconds Failed to install the app. Ensure your Android development environment is properly set up. Follow this link for setup instructions: https://reactnative.dev/docs/environment-setup. Erro ...

Accordion elements that are active will move all other content on the page

I am currently working on creating an accordion using the following code: https://codepen.io/rafaelmollad/pen/JjRZbeW. However, I have encountered a problem where when clicking on one of the accordion items, the content expands and pushes the title upward. ...

Is there a way to transfer an image from background.js to background.html?

I'm in the process of creating a chrome extension that involves making an API call every hour to retrieve an image, which I then want to save in chrome.storage.local. However, the size of the image is quite large, so I'm resizing it using a canv ...

Handling events sequentially in RxJS

Currently, I am utilizing RxJS to handle a stream of events. The processing code at the end is quite resource-intensive, such as loading a file, performing tasks, and storing data in a database. const rx = require("rxjs") // simulating numerous ...

Have you ever wondered why the React HeroIcons architecture includes React.createElement instead of simply returning plain SVG elements?

As I integrate HeroIcons into my Next.Js app, I find myself pondering over how they have structured their package architecture. The way they return icons is like this: const React = require("react"); function ArchiveIcon(props, svgRef) { retur ...

Using Vue to handle Promise resolution - incorporating Laravel Gate logic into Vue

Trying to incorporate Laravel's authorization and policy into Vue has been a challenge for me. I'm working on creating a mixin that sends a GET request to a backend controller. The issue I've encountered is that the v-if directive is receiv ...

Having issues with the POST method in node.js and express when connecting to a MySQL database

My GET method is functioning perfectly I have a database called stage4 and I am attempting to insert values into it from a frontend page The connection is established, I'm using Postman to test it first, but it keeps returning a "404 error" which is ...

Utilizing separate JavaScript files in Bootstrap 5: A guide to implementation

I am currently using Bootstrap, but I am looking to decrease the size of the Javascript files being used. My main requirements are dropdown/collapse and occasionally carousel functionalities, so I only want to include those specific scripts. Within the "d ...

Effective Ways to Redirect During or After Executing the onClick Function of Button

I am currently working on implementing a feature for my Next.js website. The functionality involves allowing users to create a new group by clicking a button, and then being redirected to an "Invite members" page with the auto-generated group_id included i ...

browsing and extracting information from JSON datasets

Currently, I am utilizing ajax to fetch a json string from the server and then employing eval to convert it into an object. However, when I loop through the data obtained from the json, only the key is displayed. Is there a way to extract the value associa ...

Issue with closing in JavaScript code not functioning as expected

I recently created a toggle bar using HTML/CSS and I attempted to implement JavaScript code to close it. However, despite my efforts, the script doesn't seem to be functioning properly. Code: $(document).ready(function(){ $(".fa-times").click(functi ...

A TypeScript class transferring data to a different class

I have a set of class values that I need to store in another class. function retainValues(data1,data2){ this.first = data1; this.second = data2; } I am looking for a way to save these class values in a different class like this -> let other = N ...

Errors during the compilation of Webgl shaders in the Google Chrome browser

Currently, I am in the process of learning three.js by following this tutorial: . Despite the tutorial working well, I have encountered errors in my own code which seem like this: ERROR: 0:26: 'nuniform' : syntax error Three.js:325 precision hi ...