From 3bfe0fdfb360e5dd0a97f0b5b961c24abd34719a Mon Sep 17 00:00:00 2001 From: Guillermo Date: Thu, 14 Sep 2023 15:50:00 +0200 Subject: [PATCH] feat: deep comparator for objects EMP-2123 --- packages/x-utils/src/__tests__/object.spec.ts | 27 ++++++++++++++ packages/x-utils/src/object.ts | 35 +++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/packages/x-utils/src/__tests__/object.spec.ts b/packages/x-utils/src/__tests__/object.spec.ts index 3431dcc303..298c1dbe02 100644 --- a/packages/x-utils/src/__tests__/object.spec.ts +++ b/packages/x-utils/src/__tests__/object.spec.ts @@ -1,6 +1,7 @@ import { cleanEmpty, cleanUndefined, + deepEqual, every, flatObject, forEach, @@ -602,4 +603,30 @@ describe('testing object utils', () => { expect(result).not.toHaveProperty('_anUndef_'); }); }); + + describe('deepEqual', () => { + it('should return true for identical objects', () => { + const obj1 = { a: 1, b: { c: 2 } }; + const obj2 = { a: 1, b: { c: 2 } }; + expect(deepEqual(obj1, obj2)).toEqual(true); + }); + + it('should return false for different objects', () => { + const obj1 = { a: 1, b: { c: 2 } }; + const obj2 = { a: 1, b: { c: 3 } }; + expect(deepEqual(obj1, obj2)).toEqual(false); + }); + + it('should return true for objects with different key order', () => { + const obj1 = { a: 1, b: 2 }; + const obj2 = { b: 2, a: 1 }; + expect(deepEqual(obj1, obj2)).toEqual(true); + }); + + it('should handle undefined correctly', () => { + const obj = { a: 1 }; + expect(deepEqual(obj, undefined)).toEqual(false); + expect(deepEqual(undefined, undefined)).toEqual(true); + }); + }); }); diff --git a/packages/x-utils/src/object.ts b/packages/x-utils/src/object.ts index e546898466..fe7736b23f 100644 --- a/packages/x-utils/src/object.ts +++ b/packages/x-utils/src/object.ts @@ -260,3 +260,38 @@ interface RenameOptions { prefix?: Prefix; suffix?: Suffix; } + +/** + * Checks if two objects are deeply equal. + * + * @param object1 - First object to compare. + * @param object2 - Second object to compare. + * + * @returns True if both objects are deeply equal. False otherwise. + * @public + */ +export function deepEqual( + object1: ObjectType | undefined, + object2: ObjectType | undefined +): boolean { + if (object1 === object2) { + return true; + } + + if (!object1 || !object2 || typeof object1 !== 'object' || typeof object2 !== 'object') { + return false; + } + + const keys1 = Object.keys(object1); + const keys2 = Object.keys(object2); + + if (keys1.length !== keys2.length) { + return false; + } + + return keys1.length !== keys2.length + ? false + : keys1.every(key => { + return keys2.includes(key) && deepEqual(object1[key], object2[key]); + }); +}