Home > Back-end >  Deep comparison of objects' properties of same type
Deep comparison of objects' properties of same type

Time:08-19

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:

{
  "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.

CodePudding user response:

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) {
            const delta = diff(valueB, aft);
            return Object.keys(delta).length > 0 ? { [keyB]: diff(valueB, aft), ...bef } : 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"
}
  • Related