Last active
February 25, 2022 01:35
-
-
Save gamedevsam/20e4a05ca570ffb4f6fb5d417811b2f3 to your computer and use it in GitHub Desktop.
Simple deep equals implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Largely based on the dequal package by lukeed, minus Date and RegExp capabilities: https://www.npmjs.com/package/dequal | |
// eslint-disable-next-line @typescript-eslint/no-explicit-any | |
export function deepEquals(foo: any, bar: any): boolean { | |
let ctor, len: number; | |
if (foo === bar) { | |
return true; | |
} | |
if (foo && bar && (ctor = foo.constructor) === bar.constructor) { | |
if (ctor === Array) { | |
if ((len = foo.length) === bar.length) { | |
while (len-- && deepEquals(foo[len], bar[len])) {} | |
} | |
return len === -1; | |
} | |
if (!ctor || typeof foo === 'object') { | |
len = 0; | |
for (ctor in foo) { | |
if ( | |
Object.prototype.hasOwnProperty.call(foo, ctor) && | |
++len && | |
!Object.prototype.hasOwnProperty.call(bar, ctor) | |
) { | |
return false; | |
} | |
if (!(ctor in bar) || !deepEquals(foo[ctor], bar[ctor])) { | |
return false; | |
} | |
} | |
return Object.keys(bar).length === len; | |
} | |
} | |
return foo !== foo && bar !== bar; | |
} | |
/** | |
* TESTS | |
*/ | |
if (!deepEquals(1, 1)) { | |
throw new Error(); | |
} //=> true | |
if (!deepEquals({}, {})) { | |
throw new Error(); | |
} //=> true | |
if (!deepEquals('foo', 'foo')) { | |
throw new Error(); | |
} //=> true | |
if (!deepEquals([1, 2, 3], [1, 2, 3])) { | |
throw new Error(); | |
} //=> true | |
if (!deepEquals(deepEquals, deepEquals)) { | |
throw new Error(); | |
} //=> true | |
if (!deepEquals(null, null)) { | |
throw new Error(); | |
} //=> true | |
if (!deepEquals(NaN, NaN)) { | |
throw new Error(); | |
} //=> true | |
if (!deepEquals([], [])) { | |
throw new Error(); | |
} //=> true | |
if (!deepEquals([{ a: 1 }, [{ b: { c: [1] } }]], [{ a: 1 }, [{ b: { c: [1] } }]])) { | |
throw new Error(); | |
} //=> true | |
if (deepEquals(1, '1')) { | |
throw new Error(); | |
} //=> false | |
if (deepEquals(null, undefined)) { | |
throw new Error(); | |
} //=> false | |
if (deepEquals({ a: 1, b: [2, 3] }, { a: 1, b: [2, 5] })) { | |
throw new Error(); | |
} //=> false | |
console.log('Success!'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment