arun kumar v
arun kumar v

Reputation: 33

Compare nested objects with arrays in JavaScript and return keys equality

I have two nested objects obj1 and obj2 and I want to compare them and the recursively return an object that for each nested key has a equality-like boolean flag

So for a given obj1 like

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 the obj2 like

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"
}

It should return

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
}

I have to compare two objects and return true for same values. And for inside the array I have to compare with ID(key) and check if prop4, prop 5 have changed and return false if changed. For Data in obj 1 and not present in obj 2 => we can neglector show as null as shown in result(equality) For Data in obj 2 and not present in obj 1 => should be flagged as true for all props in it.

The solution given by Nina Scholz in Compare nested objects in JavaScript and return keys equality has helped me but only problem I am facing is for prop3 I am getting as nested fields but I need it as same formatting as the array.

It would be very much helpful for me if any one get the right solution. I am new to JavaScript and learning it would help me a lot.

Upvotes: 3

Views: 1847

Answers (1)

Nur
Nur

Reputation: 2473

Some tricky recursion can do the job.

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

const isObject = v => v !== null && typeof v == "object";

function getDifference(x, y = x) {
    if (x === undefined) x = y;
    if (Array.isArray(x) && Array.isArray(y)) {
        const temp = [];
        for (let i = 0; i < (x.length + y.length) / 2; i++)
            temp.push(getDifference(x[i], y[i]))

        return temp;
    }
    if (isObject(x) && isObject(y)) {
        const temp = {};
        for (const key of new Set([...Object.keys(x), ...Object.keys(y)]))
            temp[key] = getDifference(x[key], y[key])

        return temp;
    }
    return x === y;
}

console.log(getDifference(obj1, obj2));

Upvotes: 3

Related Questions