Skip to content
VersionSize

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 excludes null or undefined items.

Returns

  • The transformed result of the first matching element.
  • A Promise<R> if the callback is asynchronous.
  • undefined if 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 TypeError if 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.

See Also

  • select: Transform and filter multiple elements.
  • find: Find an element without transforming it.
  • compact: Remove falsy values from an array.