Skip to content

Commit

Permalink
feat(isDeepEqual): add supports for Set (#640)
Browse files Browse the repository at this point in the history
add supports for Set

---------

Co-authored-by: Eran Hirsch <eranhirsch@gmail.com>
  • Loading branch information
clemgbld and eranhirsch committed Apr 22, 2024
1 parent 7328ce2 commit 43e44ce
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 3 deletions.
1 change: 1 addition & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ export default config(
"Promise",
"ReadonlyMap",
"RegExp",
"ReadonlySet",
],
},
],
Expand Down
47 changes: 47 additions & 0 deletions src/isDeepEqual.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,53 @@ describe("objects", () => {
});
});

describe("Sets", () => {
test("two empty sets should be equal", () => {
expect(isDeepEqual(new Set(), new Set())).toBe(true);
});

test("two sets of the same lenght should not be equal", () => {
expect(isDeepEqual(new Set([1]), new Set([1, 2]))).toBe(false);
});

test("two sets of with different primitive content should not be equal", () => {
expect(isDeepEqual(new Set([1, 2, 4]), new Set([1, 2, 3]))).toBe(false);
});

test("two sets of with the same primitive content should equal", () => {
expect(
isDeepEqual(new Set([{ a: 1 }, { b: 3 }]), new Set([{ b: 3 }, { a: 1 }])),
).toBe(true);
});

test("two sets with duplicated non primitive content should not be equal", () => {
expect(
isDeepEqual(
new Set([{ a: 1 }, { b: 3 }, { a: 1 }]),
new Set([{ b: 3 }, { a: 1 }, { b: 3 }]),
),
).toBe(false);
});

test("two sets of Maps with the same values should be equal", () => {
expect(
isDeepEqual(
new Set([new Map([["a", 123]]), new Map([["b", 456]])]),
new Set([new Map([["b", 456]]), new Map([["a", 123]])]),
),
).toBe(true);
});

test("two sets with more than two items that are all equal should be equal", () => {
expect(
isDeepEqual(
new Set([{ a: 1 }, { b: 3 }, { c: 4 }, { a: 1 }]),
new Set([{ b: 3 }, { c: 4 }, { a: 1 }, { a: 1 }]),
),
).toBe(true);
});
});

describe("arrays", () => {
test("two empty arrays are equal", () => {
expect(isDeepEqual([], [])).toBe(true);
Expand Down
40 changes: 37 additions & 3 deletions src/isDeepEqual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { purry } from "./purry";
* objects all props will be compared recursively. The built-in Date and RegExp
* are special-cased and will be compared by their values.
*
* !IMPORTANT: Sets, TypedArrays, and symbol properties of objects are not
* supported right now and might result in unexpected behavior. Please open an
* issue in the Remeda github project if you need support for these types.
* !IMPORTANT: TypedArrays and symbol properties of objects are
* not supported right now and might result in unexpected behavior. Please open
* an issue in the Remeda github project if you need support for these types.
*
* The result would be narrowed to the second value so that the function can be
* used as a type guard.
Expand Down Expand Up @@ -94,6 +94,10 @@ function isDeepEqualImplementation<T, S>(data: S | T, other: S): data is S {
return false;
}

if (data instanceof Set) {
return isDeepEqualSets(data, other as unknown as Set<unknown>);
}

if (Array.isArray(data)) {
if (data.length !== (other as ReadonlyArray<unknown>).length) {
return false;
Expand Down Expand Up @@ -174,3 +178,33 @@ function isDeepEqualMaps(

return true;
}

function isDeepEqualSets(
data: ReadonlySet<unknown>,
other: ReadonlySet<unknown>,
): boolean {
if (data.size !== other.size) {
return false;
}

// TODO: Once we bump our typescript target we can iterate over the map keys and values directly.
const dataArr = Array.from(data.values());
const otherArr = Array.from(other.values());

for (const dataItem of dataArr) {
let isFound = false;

for (let i = 0; i < otherArr.length; i++) {
if (isDeepEqualImplementation(dataItem, otherArr[i])) {
isFound = true;
otherArr.splice(i, 1);
break;
}
}
if (!isFound) {
return false;
}
}

return true;
}

0 comments on commit 43e44ce

Please sign in to comment.