Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Deep comparison of objects' properties of same type

I’m trying to compare two objects of the same type. What I want to achieve at the end, is a new object with only the properties that are different.

For example:

type A = {
    id: string;
    col: number;
    enabled: true;
    obj: {
        b: number;
    }
}

const a: A = {
    id: "ddd",
    col: 4,
    enabled: true,
    obj: {
        b: 4
    }
}

const b: A = {
    id: "dde",
    col: 4,
    enabled: true,
    obj: {
        b: 3
    }
}

const c = () => Object.values(a).reduce((bef, aft, i) => {
    const valuesB = Object.values(b);
    const keyB = Object.keys(b)[i];
    return valuesB[i] === aft ? { ...bef } : { keyB: valuesB[i], ...bef }
}, {})

With my logic above I was able to get a new object like:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

{
  "keyB": "dde"
} 

It got the value right but the key wrong and also ignored the fact that the nested object property has different values. I’m a bit stuck and out of ideas.

Any help would be extremely appreciated.

>Solution :

About the incorrect key, you’d just have to add brackets around keyB to use the value of the variable as key: { [keyB]: valueB, ...bef }

About the missing nested object, that’s a bit more complicated but here’s a solution:

const diff = <T>(obj1: T, obj2: T): Partial<T> =>
    Object.values(obj1).reduce((bef, aft, i) => {
        const valueB = Object.values(obj2)[i];
        const keyB = Object.keys(obj2)[i];
        if (valueB instanceof Object) {
            return { [keyB]: diff(valueB, aft), ...bef };
        }
        return valueB === aft ? { ...bef } : { [keyB]: valueB, ...bef };
    }, {});

const c = (): Partial<A> => diff(a, b);

You have to check each field of the nested object separately. That’s what the recursion is for.

I also added typings to the functions. Partial<A> is a copy of A but makes all fields optional.

The result is:

{
    "obj": {
        "b": 4
    },
    "id": "dde"
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading