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 } +``` diff --git a/src/object/pick.ts b/src/object/pick.ts index d5fbd45e..c2bd8897 100644 --- a/src/object/pick.ts +++ b/src/object/pick.ts @@ -1,20 +1,30 @@ +import { type FilteredKeys, filterKey, isArray, type KeyFilter } from 'radashi' + /** * Pick a list of properties from an object into a new object */ -export function pick( +export function pick>( obj: T, - keys: TKeys[], -): Pick { + filter: F, +): Pick> + +export function pick( + obj: T, + filter: KeyFilter | null, +) { if (!obj) { - return {} as Pick + 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 (Object.hasOwnProperty.call(obj, key)) { - acc[key] = obj[key] - } - return acc - }, - {} as Pick, - ) + return keys.reduce((acc, key) => { + if (filterKey(obj, key, filter)) { + acc[key] = obj[key] + } + return acc + }, {} as T) } 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, + }) + }) })