radash
radash copied to clipboard
`isEqual` does not compare Maps correctly
This test case fails:
expect(isEqual(new Map(), new Map([['1', '123']]))).toBeFalsy();
where as
expect(isEqual({}, {'1': '123'})).toBeFalsy();
succeeds. The issue is that
Reflect.ownKeys(<map>) returns an empty array. and so the keys are never compared.
Same holds for expect(isEqual(new Set(), new Set([1, 2]))).toBeFalsy();
Version: "^10.8.1", also occurs in version 11.
One solution for Maps could be:
if (a instanceof Map && b instanceof Map) {
return isEqual(Object.fromEntries(a), Object.fromEntries(b));
}
The same thing looks to happen with Set, I think for the same reason.
I patched isEqual to support Maps and Sets on any level of objects. The workaround by @Blafasel3 is only for top-level maps and is sensitive to insertion order. WARNING: My patch is insensitive to insertion order of the Map and Set entries. You could also define Maps to only be equal if the insertion order of the entries is also equal.
diff --git a/node_modules/radash/dist/cjs/typed.cjs b/node_modules/radash/dist/cjs/typed.cjs
index e3868b5..b8a2aad 100644
--- a/node_modules/radash/dist/cjs/typed.cjs
+++ b/node_modules/radash/dist/cjs/typed.cjs
@@ -72,6 +72,35 @@ const isEqual = (x, y) => {
if (x instanceof RegExp && y instanceof RegExp) {
return x.toString() === y.toString();
}
+ // patched because of https://github.com/rayepps/radash/issues/325
+ if (x instanceof Map) {
+ if (!(y instanceof Map)) {
+ return false;
+ }
+ if (x.size !== y.size) {
+ return false;
+ }
+ for (const [key, value] of x.entries()) {
+ if (!y.has(key) || !isEqual(value, y.get(key))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ if (x instanceof Set) {
+ if (!(y instanceof Set)) {
+ return false;
+ }
+ if (x.size !== y.size) {
+ return false;
+ }
+ for (const value of x) {
+ if (!y.has(value)) {
+ return false;
+ }
+ }
+ return true;
+ }
if (typeof x !== "object" || x === null || typeof y !== "object" || y === null) {
return false;
}
diff --git a/node_modules/radash/dist/esm/typed.mjs b/node_modules/radash/dist/esm/typed.mjs
index d64b1ab..21479c7 100644
--- a/node_modules/radash/dist/esm/typed.mjs
+++ b/node_modules/radash/dist/esm/typed.mjs
@@ -70,6 +70,35 @@ const isEqual = (x, y) => {
if (x instanceof RegExp && y instanceof RegExp) {
return x.toString() === y.toString();
}
+ // patched because of https://github.com/rayepps/radash/issues/325
+ if (x instanceof Map) {
+ if (!(y instanceof Map)) {
+ return false;
+ }
+ if (x.size !== y.size) {
+ return false;
+ }
+ for (const [key, value] of x.entries()) {
+ if (!y.has(key) || !isEqual(value, y.get(key))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ if (x instanceof Set) {
+ if (!(y instanceof Set)) {
+ return false;
+ }
+ if (x.size !== y.size) {
+ return false;
+ }
+ for (const value of x) {
+ if (!y.has(value)) {
+ return false;
+ }
+ }
+ return true;
+ }
if (typeof x !== "object" || x === null || typeof y !== "object" || y === null) {
return false;
}
@thomasjahoda not sure if this is maintained anymore, but maybe open a PR?
The radashi fork is accepting PRs for this.
Added testcases in this inside radashi. It was already working. Closing this and switching over.