From 42a8f99740eefdaf2c4544d2c345313f97547a36 Mon Sep 17 00:00:00 2001 From: Sebastian Lorenz Date: Sat, 7 Sep 2024 07:03:35 +0200 Subject: [PATCH] Add `RcMap.keys` and `MutableHashMap.keys` lookup functions (#3559) Co-authored-by: Tim Co-authored-by: Tim Smart --- .changeset/violet-suns-chew.md | 26 +++++++++++++++++++++ packages/effect/src/MutableHashMap.ts | 12 ++++++++++ packages/effect/src/RcMap.ts | 6 +++++ packages/effect/src/internal/rcMap.ts | 8 +++++++ packages/effect/test/MutableHashMap.test.ts | 13 +++++++++++ packages/effect/test/RcMap.test.ts | 13 +++++++++++ 6 files changed, 78 insertions(+) create mode 100644 .changeset/violet-suns-chew.md diff --git a/.changeset/violet-suns-chew.md b/.changeset/violet-suns-chew.md new file mode 100644 index 0000000000..6371200bb7 --- /dev/null +++ b/.changeset/violet-suns-chew.md @@ -0,0 +1,26 @@ +--- +"effect": minor +--- + +Added `RcMap.keys` and `MutableHashMap.keys`. + +These functions allow you to get a list of keys currently stored in the underlying hash map. + +```ts +const map = MutableHashMap.make([["a", "a"], ["b", "b"], ["c", "c"]]) +const keys = MutableHashMap.keys(map) // ["a", "b", "c"] +``` + +```ts +Effect.gen(function* () { + const map = yield* RcMap.make({ + lookup: (key) => Effect.succeed(key) + }) + + yield* RcMap.get(map, "a") + yield* RcMap.get(map, "b") + yield* RcMap.get(map, "c") + + const keys = yield* RcMap.keys(map) // ["a", "b", "c"] +}) +``` diff --git a/packages/effect/src/MutableHashMap.ts b/packages/effect/src/MutableHashMap.ts index 16071b33d5..1b5e0cabbb 100644 --- a/packages/effect/src/MutableHashMap.ts +++ b/packages/effect/src/MutableHashMap.ts @@ -159,6 +159,18 @@ export const get: { return getFromBucket(self, bucket, key) }) +/** + * @since 3.8.0 + * @category elements + */ +export const keys = (self: MutableHashMap): Array => { + const keys: Array = [] + for (const [key] of self) { + keys.push(key) + } + return keys +} + const getFromBucket = ( self: MutableHashMap, bucket: NonEmptyArray, diff --git a/packages/effect/src/RcMap.ts b/packages/effect/src/RcMap.ts index 54f0170da7..ed71100139 100644 --- a/packages/effect/src/RcMap.ts +++ b/packages/effect/src/RcMap.ts @@ -101,3 +101,9 @@ export const get: { (key: K): (self: RcMap) => Effect.Effect (self: RcMap, key: K): Effect.Effect } = internal.get + +/** + * @since 3.8.0 + * @category combinators + */ +export const keys: (self: RcMap) => Effect.Effect, E> = internal.keys diff --git a/packages/effect/src/internal/rcMap.ts b/packages/effect/src/internal/rcMap.ts index 566d8e9476..d1fece6c77 100644 --- a/packages/effect/src/internal/rcMap.ts +++ b/packages/effect/src/internal/rcMap.ts @@ -211,3 +211,11 @@ export const get: { ) } ) + +/** @internal */ +export const keys = (self: RcMap.RcMap): Effect> => { + const impl = self as RcMapImpl + return core.suspend(() => + impl.state._tag === "Closed" ? core.interrupt : core.succeed(MutableHashMap.keys(impl.state.map)) + ) +} diff --git a/packages/effect/test/MutableHashMap.test.ts b/packages/effect/test/MutableHashMap.test.ts index 5ed9cac91a..d797145450 100644 --- a/packages/effect/test/MutableHashMap.test.ts +++ b/packages/effect/test/MutableHashMap.test.ts @@ -174,6 +174,19 @@ describe("MutableHashMap", () => { ) }) + it("keys", () => { + const map = pipe( + HM.empty(), + HM.set(key(0, 0), value(0, 0)), + HM.set(key(1, 1), value(1, 1)) + ) + + expect(HM.keys(map)).toStrictEqual([ + key(0, 0), + key(1, 1) + ]) + }) + it("modifyAt", () => { const map = pipe( HM.empty(), diff --git a/packages/effect/test/RcMap.test.ts b/packages/effect/test/RcMap.test.ts index 7e353879f7..52455135f9 100644 --- a/packages/effect/test/RcMap.test.ts +++ b/packages/effect/test/RcMap.test.ts @@ -124,4 +124,17 @@ describe("RcMap", () => { // no failure means a hit assert.strictEqual(yield* RcMap.get(map, new Key({ id: 1 })), 1) })) + + it.scoped("keys lookup", () => + Effect.gen(function*() { + const map = yield* RcMap.make({ + lookup: (key: string) => Effect.succeed(key) + }) + + yield* RcMap.get(map, "foo") + yield* RcMap.get(map, "bar") + yield* RcMap.get(map, "baz") + + assert.deepStrictEqual(yield* RcMap.keys(map), ["foo", "bar", "baz"]) + })) })