pick
The pick utility finds the first element in an array that satisfies a condition and then transforms it using a callback function. It is a more powerful version of find that includes a built-in transformation step and support for asynchronous operations.
Implementation
View Source Code
ts
import { assert } from '../function/assert';
import { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';
import { isNil } from '../typed/isNil';
/**
* Picks the first element from an array that satisfies a predicate function
*
* @example
* ```ts
* const arr = [1, 2, 3, 4];
* pick(arr, x => x * x, x => x > 2) // 9
* await pick(arr, async x => x * x, x => x > 2) // 9
* ```
*
* @param array - The array to search.
* @param callback - A function that is called for each element in the array.
* @param predicate - A function that is called to validate each element in the array.
*
* @return The first element that satisfies the predicate, or undefined if no such element is found.
*
* @throws {TypeError} If the first argument is not an array.
*/
export function pick<T, R = T>(
array: T[],
callback: (item: T, index: number, array: T[]) => R,
predicate?: (item: T, index: number, array: T[]) => boolean,
): R | undefined {
assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });
const isValid = predicate ?? ((value: T) => !isNil(value));
for (let index = 0; index < array.length; index++) {
if (isValid(array[index], index, array)) {
return callback(array[index], index, array);
}
}
return undefined;
}
pick.fp = true;Features
- Isomorphic: Works in both Browser and Node.js.
- Efficient: Stops searching as soon as the first match is found.
- Integrated Transformation: Combined search and map for single elements.
- Async Support: Handle asynchronous transformation callbacks seamlessly.
API
ts
function pick<T, R>(
array: T[],
callback: (item: T, index: number, array: T[]) => R | Promise<R>,
predicate?: (item: T, index: number, array: T[]) => boolean,
): R | Promise<R> | undefined;Parameters
array: The array to search through.callback: A function that transforms the matched element. Can be synchronous or asynchronous.predicate: Optional. A function that tests each element. Defaults to a check that excludesnullorundefineditems.
Returns
- The transformed result of the first matching element.
- A
Promise<R>if the callback is asynchronous. undefinedif no element matches the predicate.
Examples
Synchronous Picking
ts
import { pick } from '@vielzeug/toolkit';
const products = [
{ id: 1, price: 100, name: 'Basic' },
{ id: 2, price: 200, name: 'Pro' },
{ id: 3, price: 300, name: 'Enterprise' },
];
// Pick the name of the first product over 150
const result = pick(
products,
(p) => p.name,
(p) => p.price > 150,
);
// 'Pro'Asynchronous Picking
ts
import { pick, delay } from '@vielzeug/toolkit';
const ids = [1, 2, 3, 4, 5];
// Fetch and return data for the first valid ID
const data = await pick(
ids,
async (id) => {
await delay(100);
return { id, data: 'fetched' };
},
(id) => id % 2 === 0,
);
// { id: 2, data: 'fetched' }Implementation Notes
- Throws
TypeErrorif the first argument is not an array. - Short-circuiting: The callback is only executed once for the first item that passes the predicate.
- If no predicate is provided, it returns the result of the callback for the first non-nil element in the array.