From ffd79fe1ec6c59cb3684a84c15b66761aa186bf1 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:54:42 -0400 Subject: [PATCH 1/4] feat(pick): accept a callback for advanced picking --- src/object/pick.ts | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/object/pick.ts b/src/object/pick.ts index d5fbd45e..e1bab4ad 100644 --- a/src/object/pick.ts +++ b/src/object/pick.ts @@ -1,20 +1,20 @@ +import { type FilteredKeys, type KeyFilter, reduceKeys } from "radashi"; + /** * Pick a list of properties from an object into a new object */ -export function pick( - obj: T, - keys: TKeys[], -): Pick { - if (!obj) { - return {} as Pick - } - return keys.reduce( - (acc, key) => { - if (Object.hasOwnProperty.call(obj, key)) { - acc[key] = obj[key] - } - return acc - }, - {} as Pick, - ) +export function pick>( + obj: T, + filter: F, +): Pick> { + if (!obj) return {} as any; + return reduceKeys( + obj, + filter, + (acc, value, key) => { + acc[key] = value; + return acc; + }, + {} as any, + ); } From 3df170c7da86eee71b204725c3edfa4672d017bd Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sun, 7 Jul 2024 19:04:51 -0400 Subject: [PATCH 2/4] stop using reduceKeys This saves us 77 bytes. --- src/object/pick.ts | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/object/pick.ts b/src/object/pick.ts index e1bab4ad..c2bd8897 100644 --- a/src/object/pick.ts +++ b/src/object/pick.ts @@ -1,20 +1,30 @@ -import { type FilteredKeys, type KeyFilter, reduceKeys } from "radashi"; +import { type FilteredKeys, filterKey, isArray, type KeyFilter } from 'radashi' /** * Pick a list of properties from an object into a new object */ export function pick>( - obj: T, - filter: F, -): Pick> { - if (!obj) return {} as any; - return reduceKeys( - obj, - filter, - (acc, value, key) => { - acc[key] = value; - return acc; - }, - {} as any, - ); + obj: T, + filter: F, +): Pick> + +export function pick( + obj: T, + filter: KeyFilter | null, +) { + if (!obj) { + return {} + } + let keys: (keyof T)[] = filter as any + if (isArray(filter)) { + filter = null + } else { + keys = Reflect.ownKeys(obj) as (keyof T)[] + } + return keys.reduce((acc, key) => { + if (filterKey(obj, key, filter)) { + acc[key] = obj[key] + } + return acc + }, {} as T) } From 34be3ef9bd45b5e8a013916698b1af179332fe90 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sun, 7 Jul 2024 19:08:01 -0400 Subject: [PATCH 3/4] update `pick` docs --- docs/object/pick.mdx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/object/pick.mdx b/docs/object/pick.mdx index cad2a5b3..7aed8f03 100644 --- a/docs/object/pick.mdx +++ b/docs/object/pick.mdx @@ -1,6 +1,6 @@ --- title: pick -description: Pick only the desired attributes from an object +description: Pick only the desired properties from an object --- ## Basic usage @@ -19,3 +19,18 @@ const fish = { _.pick(fish, ['name', 'source']) // => { name, source } ``` + +### Predicate function + +The `pick` function can also accept a predicate function as the filter argument. This allows for more complex filtering logic beyond simple key inclusion or exclusion. + +```ts +import * as _ from 'radashi' + +const source = { a: 1, b: 2, c: 3, d: 4 } + +_.pick(source, (value, key) => { + return value % 2 === 0 // Include only even values +}) +// => { b: 2, d: 4 } +``` From b6e11ec41f0c4cf16e125934dc79a8074032cef0 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Sun, 7 Jul 2024 19:10:25 -0400 Subject: [PATCH 4/4] add a test --- tests/object/pick.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/object/pick.test.ts b/tests/object/pick.test.ts index d4c381d7..36921354 100644 --- a/tests/object/pick.test.ts +++ b/tests/object/pick.test.ts @@ -79,4 +79,11 @@ describe('pick', () => { a: 2, }) }) + test('works with predicate function', () => { + const result = _.pick({ a: 1, b: 2, c: 3, d: 4 }, value => value % 2 === 0) + expect(result).toEqual({ + b: 2, + d: 4, + }) + }) })