Utilize Javascript to compare nested objects and store the differences in a separate object

I have a dilemma involving two JavaScript objects

var order1 = {
    sandwich: 'tuna',
    chips: true,
    drink: 'soda',
    order: 1,
    toppings: [{VendorNumber: 18, PreferredFlag: false, SupportedFlag: true}, {VendorNumber: 19, PreferredFlag: false, SupportedFlag: true}, {VendorNumber: 20, PreferredFlag: false, SupportedFlag: true}],
    details: {
        name: 'Chris',
        phone: '555-555-5555',
        email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5f31301f2b373e313426302a713c3032">[email protected]</a>'
    },
    otherVal1: '1'
};

var order2 = {
    sandwich: 'turkey',
    chips: true,
    drink: 'soda',
    order: 2,
    toppings: [{VendorNumber: 18, PreferredFlag: false, SupportedFlag: true}, {VendorNumber: 19, PreferredFlag: false, SupportedFlag: false}, {VendorNumber: 20, PreferredFlag: true, SupportedFlag: true}],
    details: {
        name: 'Jon',
        phone: '(555) 555-5555',
        email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="38415d4b7848545d594b5d165b5755">[email protected]</a>'
    },
    otherVal1: '2'
};

The challenge is to compare these two objects (order1 being the original and order2 as the edited data), and store the differences in a new variable named var order3. It is important that when there is an array inside an object like the toppings array, it should be copied as a whole with any changes included.

In essence, the desired result would look like this:

{
  details: {
    email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="265f435566564a434755430845494b">[email protected]</a>",
    name: "Jon",
    phone: "(555) 555-5555"
  },
  order: 2,
  otherVal1: "2",
  sandwich: "turkey",
  toppings: [{
  PreferredFlag: false,
  SupportedFlag: true,
  VendorNumber: 18
}, {
  PreferredFlag: false,
  SupportedFlag: false,
  VendorNumber: 19
}, {
  PreferredFlag: true,
  SupportedFlag: true,
  VendorNumber: 20
}]
}

How can I accomplish this task?

Answer №1

This function is designed to provide the exact output you are looking for:

function findDifference(target, source) {

    if (Array.isArray(target)) { // check if input is an array
        return target; // simply return it
    }

    var result = {};
    for (var key in target) { // iterate through all keys
        if (typeof source[key] === "object") { // if value is another object or array
            result[key] = findDifference(target[key], source[key]); // recursively find differences
        } else if (source[key] !== target[key]) { // if value has changed
            result[key] = target[key]; // use the new value
        }
        // otherwise, ignore
    }
    return result;
}
console.log(findDifference(updatedOrder, originalOrder));

Answer №2

If you're in need of a comparison algorithm, consider using a custom recursive function like the one below. This function will iterate through each property of a JavaScript object to check for equality. Keep in mind that the order of arguments can impact the output.

function findDifferences(object1, object2) {
    if (typeof object1 === "object") {
        const diffObject = {};
        for (const property in object1) {
            if (findDifferences(object1[property], object2[property])) {
                diffObject[property] = object1[property];
            }
        }
        return diffObject;
    } else {
        return object1 !== object2;
    }
}

console.log(findDifferences(order2, order1));

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 method for testing an Angular service that has dependencies in Jasmine?

My service implementation is structured as follows: angular.module('app').service('MyService' , function (dependency1, dependency2, dependency3 ...) { function funcToTest() { // Do something } } I am wondering how I ca ...

Is it possible to generate distance between 2 elements without utilizing padding or margin?

In my React Native project, I'm currently working with 2 inline buttons - the search and add buttons: https://i.stack.imgur.com/tKZrf.png I'm looking to add some spacing between these buttons without impacting their alignment with the left and ...

Inconsistencies with jQuery.ajax event triggering in IE8, works only when Fiddler is activated

This has to be one of the strangest errors I've ever come across: So I have a series of jQuery.ajax calls to a web service that I put together. It works perfectly in Firefox and Chrome, but in IE8 it just refuses to work unless I have Fiddler running ...

Auto-updating Angular $scope variables

I am facing an issue with two variables in my code. Whenever I update one variable, the other variable also gets updated automatically. Can someone please help me understand what is causing this behavior? $scope.pages = []; $scope.pagesSave = []; var fun ...

Incorporating a custom transpiled file format into Typescript imports

I am trying to import a file format .xyz that does not have fixed types for all instances of the format: import { Comment, Article, User } from "./Blog.xyz" However, I keep getting this error message: TS2307: Cannot find module './Blog.xy ...

Dealing with redirect issues in a React-Material menu: A guide to troubleshooting and

When working with my menu, I face a variety of issues. First and foremost, within the initial RETURN section, there is a TREEITEM with a LISTITEM and a LISTITETEXT. I have included an OnClick event in the LISTITETEXT so that if the menu's id matches ...

Node JS Axios Network Error due to CORS Policy Restrictions

When attempting to make a put axios request, I encounter the following error: https://i.sstatic.net/aBQGI.png I have installed and enabled the CORS module in the server.js file, but it doesn't seem to be working. Additionally, there are no CORS head ...

Comparing the efficiency of using arrays versus mapping to an object and accessing data in JavaScript

When considering the basics of computer science, it is understood that searching an unsorted list typically occurs in O(n) time, while direct access to an element in an array happens in O(1) time for HashMaps. So, which approach yields better performance: ...

Proto-Type Namespace

I have a class named "Animals" which serves as a namespace for other classes, "Crocodile" and "Monkey": var Monkey = function(Animals) { this.Animals = Animals; }; Monkey.prototype.feedMe = function() { this.Animals.feed(); }; var Crocodile = functi ...

Node-fetch enables dynamic requests

Seeking to retrieve real-time data from a fast-updating API has posed a challenge for me. The issue lies in my code constantly returning the same value. I've experimented with two approaches: var fetch = require("node-fetch"); for(let i=0; i<5; i+ ...

Store <td> in a variable

At the moment, I have a script that allows users to input an item name, along with its size, color, and other options. Each of these entries is saved as individual items with their custom specifications, such as a black t-shirt in large size. The script c ...

What is the best way to ensure that this <span> maintains a consistent width, no matter what content is placed inside

So here's the deal, I've got some dynamically generated html going on where I'm assigning 1-6 scaled svgs as children of a . The span is inline with 2 other spans to give it that nice layout: https://i.sstatic.net/mySYe.png I want these "b ...

Utilizing Electron API within an Angular Component

I'm hoping to utilize a locally stored video file in electron and play it within my angular component. Despite exposing the loadLocalFile function to prevent the need for setting nodeIntegration to true, I keep receiving a Security Warning : This re ...

The Node.contains() function in JavaScript does not verify the presence of inner child elements

I have developed a custom DatePicker component for my React app and I am facing an issue with hiding it on outside click, similar to how I handled other components like Select Dropdown. To address this problem, I created a custom hook: export default (ref, ...

Pull To Refresh Fails To Update JSON Data

I have been attempting to add a Pull to Refresh feature to my tableview in order to update JSON Data from the server. The issue arises when I try to reload the data - while it appears to be reloading in the debug Area, the labels and images within the ce ...

Having trouble with my Express.js logout route not redirecting, how can I troubleshoot and resolve it?

The issue with the logout route not working persists even when attempting to use another route, as it fails to render or redirect to that specific route. However, the console.log("am clicked"); function works perfectly fine. const express = require('e ...

Tips for showing an external website while maintaining the application header

As a newcomer to Phonegap, I am currently experimenting with Intel XDK. Is there a way for me to load an external website while keeping my own custom header intact? Currently, all I am doing to load the external site is window.location = "http://google.c ...

React form submissions result in FormData returning blank data

I am having trouble retrieving the key-value pair object of form data when the form is submitted, using the new FormData() constructor. Unfortunately, it always returns empty data. Despite trying event.persist() to prevent react event pooling, I have not ...

Obtaining NodeJS from a mysterious subdirectory

-- plugins ---- myplugin1 ------ core ---- myplugin2 ------ core If this represents the directory structure, is there a method to import all core directories from plugins without specifying the specific plugin names like myplugin1? require('/plugins ...

Tips for parsing nested JSON arrays with Python?

Is there a way to extract the accountNumber, name, and phoneNumber values separately from a JSON response using Python? [{ "msg": "result", "id": "testdata", "result": [{ "accountNumber": "123456", "name": "CHRISfarmece", ...