From e133c1ba8c3d8c1a8e3d2da4fa06e1f77a2036ec Mon Sep 17 00:00:00 2001 From: Alisue Date: Wed, 17 Jan 2024 22:32:45 +0900 Subject: [PATCH 1/2] feat(collections): Add `pick` and `omit` --- collections/mod.ts | 2 ++ collections/omit.ts | 26 ++++++++++++++++++++++++++ collections/omit_test.ts | 38 ++++++++++++++++++++++++++++++++++++++ collections/pick.ts | 22 ++++++++++++++++++++++ collections/pick_test.ts | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+) create mode 100644 collections/omit.ts create mode 100644 collections/omit_test.ts create mode 100644 collections/pick.ts create mode 100644 collections/pick_test.ts diff --git a/collections/mod.ts b/collections/mod.ts index 93760b045bec..f8f2135d86fc 100644 --- a/collections/mod.ts +++ b/collections/mod.ts @@ -54,3 +54,5 @@ export * from "./drop_last_while.ts"; export * from "./reduce_groups.ts"; export * from "./sample.ts"; export * from "./running_reduce.ts"; +export * from "./pick.ts"; +export * from "./omit.ts"; diff --git a/collections/omit.ts b/collections/omit.ts new file mode 100644 index 000000000000..a25c4851259e --- /dev/null +++ b/collections/omit.ts @@ -0,0 +1,26 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +/** + * Creates a new object by excluding the specified keys from the provided object. + * + * @example + * ```ts + * import { omit } from "https://deno.land/std@$STD_VERSION/collections/omit.ts"; + * import { assertEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_equals.ts"; + * + * const obj = { a: 5, b: 6, c: 7, d: 8 }; + * const omitted = omit(obj, ["a", "c"]); + * + * assertEquals(omitted, { b: 6, d: 8 }); + * ``` + */ +export function omit( + obj: T, + keys: K[], +): Omit { + const excludes = new Set(keys); + const has = excludes.has.bind(excludes); + return Object.fromEntries( + Object.entries(obj).filter(([k, _]) => !has(k as K)), + ) as Omit; +} diff --git a/collections/omit_test.ts b/collections/omit_test.ts new file mode 100644 index 000000000000..cd2b701d2b52 --- /dev/null +++ b/collections/omit_test.ts @@ -0,0 +1,38 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import { assertEquals, assertNotStrictEquals } from "../assert/mod.ts"; +import { omit } from "./omit.ts"; + +Deno.test({ + name: "omit() returns a new object from the provided object", + fn() { + const obj = { a: 5, b: 6, c: 7, d: 8 }; + const omitted = omit(obj, []); + + assertEquals(omitted, { a: 5, b: 6, c: 7, d: 8 }); + assertNotStrictEquals(omitted, obj); + }, +}); + +Deno.test({ + name: + "omit() returns a new object from the provided object without the provided keys", + fn() { + const obj = { a: 5, b: 6, c: 7, d: 8 }; + const omitted = omit(obj, ["a", "c"]); + + assertEquals(omitted, { b: 6, d: 8 }); + assertNotStrictEquals(omitted, obj); + }, +}); + +Deno.test({ + name: "omit() returns an empty object when the provided keys is empty", + fn() { + const obj = { a: 5, b: 6, c: 7, d: 8 }; + const omitted = omit(obj, ["a", "b", "c", "d"]); + + assertEquals(omitted, {}); + assertNotStrictEquals(omitted, obj); + }, +}); diff --git a/collections/pick.ts b/collections/pick.ts new file mode 100644 index 000000000000..e0fc75a1b957 --- /dev/null +++ b/collections/pick.ts @@ -0,0 +1,22 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +/** + * Creates a new object by including the specified keys from the provided object. + * + * @example + * ```ts + * import { pick } from "https://deno.land/std@$STD_VERSION/collections/pick.ts"; + * import { assertEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_equals.ts"; + * + * const obj = { a: 5, b: 6, c: 7, d: 8 }; + * const picked = pick(obj, ["a", "c"]); + * + * assertEquals(picked, { a: 5, c: 7 }); + * ``` + */ +export function pick( + obj: T, + keys: K[], +): Pick { + return Object.fromEntries(keys.map((k) => [k, obj[k]])) as Pick; +} diff --git a/collections/pick_test.ts b/collections/pick_test.ts new file mode 100644 index 000000000000..1af6d6f3a90c --- /dev/null +++ b/collections/pick_test.ts @@ -0,0 +1,39 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +import { assertEquals, assertNotStrictEquals } from "../assert/mod.ts"; +import { pick } from "./pick.ts"; + +Deno.test({ + name: "pick() returns a new empty object when no keys are provided", + fn() { + const obj = { a: 5, b: 6, c: 7, d: 8 }; + const picked = pick(obj, []); + + assertEquals(picked, {}); + assertNotStrictEquals(picked, obj); + }, +}); + +Deno.test({ + name: + "pick() returns a new object from the provided object with the provided keys", + fn() { + const obj = { a: 5, b: 6, c: 7, d: 8 }; + const picked = pick(obj, ["a", "c"]); + + assertEquals(picked, { a: 5, c: 7 }); + assertNotStrictEquals(picked, obj); + }, +}); + +Deno.test({ + name: + "pick() returns a new object from the provided object with the provided keys (all keys are provided)", + fn() { + const obj = { a: 5, b: 6, c: 7, d: 8 }; + const picked = pick(obj, ["a", "b", "c", "d"]); + + assertEquals(picked, { a: 5, b: 6, c: 7, d: 8 }); + assertNotStrictEquals(picked, obj); + }, +}); From ef8df5d89656ceaeb0c7046e1a66a586b3d764b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=9Blisue=20=28Ali=20sue=E3=83=BB=E3=81=82=E3=82=8A?= =?UTF-8?q?=E3=81=99=E3=81=88=29?= Date: Tue, 13 Feb 2024 17:19:28 +0900 Subject: [PATCH 2/2] feat(collection: Use `readonly` for arguments Co-authored-by: Kenta Moriuchi --- collections/omit.ts | 4 ++-- collections/pick.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/collections/omit.ts b/collections/omit.ts index a25c4851259e..06565eca0081 100644 --- a/collections/omit.ts +++ b/collections/omit.ts @@ -15,8 +15,8 @@ * ``` */ export function omit( - obj: T, - keys: K[], + obj: Readonly, + keys: readonly K[], ): Omit { const excludes = new Set(keys); const has = excludes.has.bind(excludes); diff --git a/collections/pick.ts b/collections/pick.ts index e0fc75a1b957..e508635d922d 100644 --- a/collections/pick.ts +++ b/collections/pick.ts @@ -15,8 +15,8 @@ * ``` */ export function pick( - obj: T, - keys: K[], + obj: Readonly, + keys: readonly K[], ): Pick { return Object.fromEntries(keys.map((k) => [k, obj[k]])) as Pick; }