select
The select utility is a high-performance combined transformation and filtering tool. It allows you to simultaneously map and filter an array in a single pass, and it provides built-in 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';
import { isPromise } from '../typed/isPromise';
import type { CallbackDynamic, Predicate, ResultArray } from '../types';
/**
* 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]
* await select(arr, async x => x * x, x => x > 2) // [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, C extends CallbackDynamic<T, R>>(
array: T[],
callback: C,
predicate?: Predicate<T>,
): ResultArray<C> {
assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });
const result = [];
const isValid = predicate ?? ((value: T) => !isNil(value));
for (let index = 0; index < array.length; index++) {
if (isValid(array[index], index, array)) {
result.push(callback(array[index], index, array));
}
}
return (isPromise(callback) ? Promise.all(result) : result) as ResultArray<C>;
}
select.fp = true;Features
- Isomorphic: Works in both Browser and Node.js.
- Combined Operation: Map and filter in one step for better readability and performance.
- Async Support: Handle asynchronous mapping functions seamlessly.
- Intelligent Defaults: Automatically filters out
nullorundefinedresults by default.
API
ts
function select<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[]>;Parameters
array: The array to process.callback: A transformation function that receives each element and returns a new value (or a Promise for one).predicate: Optional. A function that decides which elements from the original array should be processed by the callback. Defaults to a check that excludesnullorundefineditems.
Returns
- A new array of transformed elements.
- A
Promise<R[]>if the callback is asynchronous.
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
ts
import { select, delay } from '@vielzeug/toolkit';
const ids = [1, 2, 3];
// Fetch data for specific IDs
const details = await select(
ids,
async (id) => {
await delay(50); // Simulate API latency
return { id, status: 'ok' };
},
(id) => id !== 2,
);
// [{ id: 1, ... }, { id: 3, ... }]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. - When using async callbacks, all transformations are initiated concurrently.
- If no predicate is provided, it uses a standard "is defined" check on the input elements.