Exploring the similarities between nested objects and arrays in JavaScript when comparing and determining key equality

In my scenario, I am dealing with two nested objects named obj1 and obj2. The goal is to compare these objects recursively and then return another object in which each nested key will have a boolean flag indicating equality.

For instance, consider an obj1 like this:

var obj1 = {
    prop1: "BAR",
    prop2: "foo",
    prop3: [
        {
            id: 1,
            prop4: "foo",
            prop5: "a"
        },
        {
            id: 2,
            prop4: "foo",
            prop5: "b"
        },
        {
            id: 3,
            prop4: "foo",
            prop5: "e"
        }
    ]
}

And an obj2 like this:

var obj2 = {
    prop1: "FOO",
    prop2: "foo",
    prop3: [
        {
            id: 1,
            prop4: "bar",
            prop5: "b"
        },
        {
            id: 2,
            prop4: "foo",
            prop5: "a"
        },
        {
            id: 4,
            prop4: "foo",
            prop5: "e"
        }
    ],
    prop6: "new"
}

The expected output should be:

var equality = {
    prop1: false,
    prop2: true,
    prop3: [
        {
            id: 1,
            prop4: false,
            prop5: false
        },
        {
            id: 2,
            prop4: true,
            prop5: false
        },
        {
            id: 3,
            prop4: null,
            prop5: null
        },
        {
            id: 4,
            prop4: true,
            prop5: true
        }
    ],
    prop6: true
}

In order to achieve this, I need to compare both objects and return true for matching values. When comparing arrays within the objects, I must use the ID as the key and check if prop4 and prop5 have changed, returning false if they have changed. For data present in obj1 but not in obj2, it should show as null in the result (equality). Data that is only present in obj2 should be flagged as true for all its properties.

I found a solution by Nina Scholz on Stack Overflow, which helped me greatly. The only issue I am facing is regarding the formatting of prop3. I would appreciate it if someone could provide a more suitable solution. As a beginner in JavaScript, learning from this experience would be incredibly valuable.

Answer №1

Using clever recursion is the key to solving this problem.

let firstObject = { val1: 1, val2: "bar", val3: [{ num: 1, value4: "baz", value5: "x" }, { num: 2, value4: "foo", value5: "y" }] }
let secondObject = { val1: 3, val2: "bar", val3: [{ num: 1, value4: "lorem", value5: "y" }, { num: 2, value4: "foo", value5: "x" }, { num: 3, value4: "foo", value5: "z" }], val6: "new" }

const checkIfObject = data => data !== null && typeof data === "object";

function findDifference(data1, data2 = data1) {
    if (data1 === undefined) data1 = data2;
    
    if (Array.isArray(data1) && Array.isArray(data2)) {
        const resultArr = [];
        
        for (let i = 0; i < (data1.length + data2.length) / 2; i++) {
            resultArr.push(findDifference(data1[i], data2[i]));
        }

        return resultArr;
    }
    
    if (checkIfObject(data1) && checkIfObject(data2)) {
        const resultObj = {};
        
        for (const property of new Set([...Object.keys(data1), ...Object.keys(data2)])) {
            resultObj[property] = findDifference(data1[property], data2[property]);
        }

        return resultObj;
    }
    
    return data1 === data2;
}

console.log(findDifference(firstObject, secondObject));

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

Creating unique page styles using global styles in Next.js

I am facing a dilemma in my NextJS app. On the /home page, I need to hide the x and y overflow, while on the /books page, I want the user to be able to scroll freely. The issue is that Next only allows for one global stylesheet and using global CSS selec ...

Implementing Real-Time Search Feature Using AJAX

Exploring the world of search functions for the first time, I decided to implement an AJAX function to call a PHP file on key up. However, I encountered some strange behavior as the content in the display area was changing, but not to the expected content. ...

Utilize the Algolia search-insights library in conjunction with React

Trying to integrate the Search-Insights Library from Algolia with React using npm for installation instead of just adding it to the header as shown in the example. Example of implementation in React Click here for React implementation example <script ...

Transferring user information from Node.js server to Angular upon successful login

Attempting to login my user through Facebook using PassportJS and passing the user data to Angular has been a challenge. On the server side, everything seems fine with the code for the Facebook callback in the users controller: exports.facebookCallback = ...

Node: Exploring folders through recursive traversal

Node.js is a new world to me, and I'm determined to grasp its async behavior and callback structure. Here's where I'm currently struggling: // IMPORT ------------------------------------------------------------------------ fs = r ...

Help Needed: Adding a Simple Element to jQuery Tabs Script

I recently came across a fantastic jQuery tabs script on a website called Tutorialzine. The link to the article can be found here. As I was implementing this script, I realized I needed to customize it by adding specific classes to certain tabs. Specifica ...

Ways to extract the element index while iterating through a VBA Array

I've been using this VBA code to iterate through an array (supplier_reports()) and it's been working well. However, I'm curious if there's a way to retrieve the element number when processing the array values: For Each x In supplier_re ...

Updating the state value of a variable that utilizes a custom Hook: a step-by-step guide

After watching a video by Dan Abramov, I decided to optimize my component by creating a custom Hook called useFormInput. This hook handles the state and onChange functionality for all of my form input fields. Everything was working perfectly until I neede ...

Contrasting behavior in JavaScript experienced in development versus production environments

I've been working on an application that, when given certain data, generates a diagram using JavaScript in conjunction with the kineticJS framework. During development, everything is smooth sailing, but once deployed to production (Heroku), things st ...

Tips for sending a set to a directive in angular.js?

Forgive me for my confusion. I am passing the name of a collection to my directive: <ul tag-it tag-src="preview_data.preview.extract.keywords"><li>Tag 1</li><li>Tag 2</li></ul> This is how the directive is defined: a ...

How to implement a "callWhenReady" function in JavaScript

I am new to javascript and currently working on restructuring my prototype code. The current setup involves multiple levels of nested callbacks, making it difficult to read and manage. I am aiming for a cleaner approach similar to the following: GoogleMap ...

Creating the Apk file for your sencha touch application

Hello there! I'm diving into the world of Sencha Touch as a new user. After installing all the required tools and SDK, I successfully set up the demo example that came with project creation via command line. Now, I'm eager to generate the APK fil ...

Tips for extracting only a portion of the JavaScript timestamp

I have a JavaScript timestamp that reads Tue Sep 30 2014 12:02:50 GMT-0400 (EDT). When I use the .getTime() method, I get 1412092970.768 Typically, this timestamp represents a specific time of today. My question is whether it's possible to extract o ...

When state is updated, the component is re-rendered multiple times

I am working on setting the state in componentDidMount lifecycle method to verify data from local storage. Depending on whether the data exists in local storage, I either redirect the user to the login page or keep them on the dashboard. Is there a way to ...

PhantomJS Karma encountering SyntaxError when trying to export variables

I've encountered an issue while running Karma and PhantomJS. When I attempt to run, the console displays the following message: 22 03 2016 14:58:47.865:WARN [karma]: No captured browser, open http://localhost:9876/ 22 03 2016 14:58:47.875:INFO [karm ...

ways to display view without page refresh in mvc3

@using (Html.BeginForm("Index", "HRBankInfo", FormMethod.Get)) { <div align="center" class="display-label"> @ViewBag.message <br /><input type="submit" value="Ok" /> </div> } This particular partial view is display ...

Different options for determining network connectivity on a website

Seeking Network and Location Information on ASP.Net Core MVC Web Application After some investigation, I came across the Navigator API online. For acquiring location data, it functions flawlessly. navigator.geolocation.getCurrentPosition(function (posi ...

Starting point for Angular 2 app setup

What is the best way to handle data initialization in my app? For instance, if a user logs in and presses F5, I need to retrieve the current user data from the server before any other queries are executed, such as getting the user's orders. In Angular ...

The AudioContext feature is functioning properly on Google Chrome but experiencing issues on Safari

In Safari, I understand that audio context needs to be created after user interaction. Despite this knowledge, the code below still didn't produce the desired result. HTML <button onclick="play">Play</button> Javascript functio ...

Using a jQuery dialog to launch a popup window specifically optimized for Safari browsers

I recently encountered an issue with my plain JavaScript function that opens a pop-up window. It functions perfectly in Chrome and Firefox, but I faced difficulty in Safari due to the default popup blocker preventing the page from opening without any err ...