select
The select utility maps and filters an array in a single pass. A predicate function decides which elements are processed; elements failing the predicate are excluded from the result. When no predicate is given, null and undefined elements in the source array are automatically skipped.
Source Code
View Source Code
ts
import type { Predicate } from '../types';
import { assert } from '../function/assert';
import { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';
import { isNil } from '../typed/isNil';
/**
* Selects elements from an array based on a callback function and an optional predicate function.
*
* @example
* ```ts
* const arr = [1, 2, 3, 4];
* select(arr, x => x * x, x => x > 2) // [9, 16]
* select(arr, x => x * x) // [1, 4, 9, 16]
* ```
*
* @param array - The array to select from.
* @param callback - The function to map the values.
* @param [predicate] - (optional) The function to filter the values.
*
* @returns A new array with the selected values.
*
* @throws {TypeError} If the provided array is not an array.
*/
export function select<T, R>(
array: T[],
callback: (item: T, index: number, array: T[]) => R,
predicate?: Predicate<T>,
): R[] {
assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });
const isValid = predicate ?? ((value: T) => !isNil(value));
const result: R[] = [];
for (let index = 0; index < array.length; index++) {
if (isValid(array[index], index, array)) {
result.push(callback(array[index], index, array));
}
}
return result;
}Features
- Isomorphic: Works in both Browser and Node.js.
- Single Pass: Map and filter in one iteration for readability and performance.
- Flexible Predicate: Pass an explicit predicate to control which elements are processed.
- Nil Filtering: Without a predicate,
nullandundefinedsource elements are automatically skipped.
API
ts
function select<T, R>(
array: T[],
callback: (item: T, index: number, array: T[]) => R,
predicate?: (item: T, index: number, array: T[]) => boolean,
): R[];Parameters
array: The input array.callback: Transformation applied to each element that passes the predicate.predicate: Optional. Filters the input elements before mapping. Defaults to!isNil(element)— skipsnullandundefinedsource values.
Returns
A new array containing the mapped values of elements that passed the predicate.
Examples
Synchronous Selection
ts
import { select } from '@vielzeug/toolkit';
const numbers = [10, 20, 30, 40];
// Double only the numbers greater than 20
const result = select(
numbers,
(x) => x * 2,
(x) => x > 20,
);
// [60, 80]Asynchronous Selection
WARNING
select does not support async callbacks. Use parallel or Promise.all for async mapping:
ts
import { parallel } from '@vielzeug/toolkit';
const ids = [1, 2, 3];
const details = await parallel(3, ids, async (id) => fetchUser(id));Default Filtering
ts
import { select } from '@vielzeug/toolkit';
const data = [1, null, 2, undefined, 3];
// Automatically skips the null/undefined values
const doubled = select(data, (x) => x * 2);
// [2, 4, 6]Implementation Notes
- Throws
TypeErrorif the first argument is not an array. - The predicate filters source elements, not callback results. To filter
nullcallback results, usepredicateexplicitly or useArray.filterafter. - If no predicate is provided, it uses
!isNil(element)on the original input.