sort
The sort utility returns a new sorted array and supports two modes:
- single-field sorting via selector function
- multi-field sorting via object selector (
{ key: 'asc' | 'desc' })
Source Code
View Source Code
ts
import { assert } from '../function/assert';
import { compare } from '../function/compare';
import { compareBy } from '../function/compareBy';
import { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';
export type SortDirection = 'asc' | 'desc';
export type SortSelectors<T> = Partial<Record<keyof T, SortDirection>>;
/**
* Sorts an array by a selector function (single-field) or by a multi-field
* object of `{ key: 'asc' | 'desc' }` entries.
*
* @example
* ```ts
* // Single field
* sort([{ a: 2 }, { a: 1 }], item => item.a); // [{ a:1 }, { a:2 }]
* sort([{ a: 2 }, { a: 1 }], item => item.a, 'desc'); // [{ a:2 }, { a:1 }]
*
* // Multi-field
* sort(users, { name: 'asc', age: 'desc' });
* ```
*
* @param array - The array to sort.
* @param selector - A function extracting the sort key, or a multi-field object.
* @param direction - `'asc'` (default) or `'desc'` — only applies to single-field mode.
* @returns A new sorted array.
*
* @throws {TypeError} If the first argument is not an array.
*/
export function sort<T>(array: T[], selector: (item: T) => unknown, direction?: SortDirection): T[];
export function sort<T>(array: T[], selectors: SortSelectors<T>): T[];
export function sort<T>(
array: T[],
selectorOrSelectors: ((item: T) => unknown) | SortSelectors<T>,
direction: SortDirection = 'asc',
): T[] {
assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });
if (typeof selectorOrSelectors === 'function') {
const multiplier = direction === 'desc' ? -1 : 1;
return [...array].sort((a, b) => compare(selectorOrSelectors(a), selectorOrSelectors(b)) * multiplier);
}
return [...array].sort(compareBy(selectorOrSelectors));
}Features
- Isomorphic: Works in both Browser and Node.js.
- Immutable: Returns a new sorted array, leaving the original untouched.
- Selector Support: Sort by any property or computed value.
- Multi-Field Support: Sort by multiple keys with independent directions.
- Custom Order: Supports
'asc'and'desc'.
API
ts
type SortDirection = 'asc' | 'desc';
type SortSelectors<T> = Partial<Record<keyof T, SortDirection>>;
function sort<T>(array: T[], selector: (item: T) => unknown, direction?: SortDirection): T[];
function sort<T>(array: T[], selectors: SortSelectors<T>): T[];Parameters
array: The array to sort.selector: A function that extracts the value to compare from each element.direction: Optional.'asc'by default,'desc'for descending order.selectors: Object-based multi-field selector. Each key maps to'asc'or'desc'.
Returns
- A new sorted array.
Examples
Sorting Numbers
ts
import { sort } from '@vielzeug/toolkit';
const numbers = [10, 2, 33, 4, 1];
// Ascending (default)
sort(numbers, (n) => n); // [1, 2, 4, 10, 33]
// Descending
sort(numbers, (n) => n, 'desc'); // [33, 10, 4, 2, 1]Sorting Objects
ts
import { sort } from '@vielzeug/toolkit';
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 20 },
{ name: 'Charlie', age: 30 },
];
// Sort by age
const byAge = sort(users, (u) => u.age);
// [{ name: 'Bob', ... }, { name: 'Alice', ... }, { name: 'Charlie', ... }]Sorting by Multiple Fields
ts
import { sort } from '@vielzeug/toolkit';
const employees = [
{ team: 'A', score: 10, name: 'Chris' },
{ team: 'B', score: 12, name: 'Alex' },
{ team: 'A', score: 12, name: 'Bea' },
{ team: 'A', score: 12, name: 'Anna' },
];
const ordered = sort(employees, { score: 'desc', name: 'asc' });
// [
// { team: 'B', score: 12, name: 'Alex' },
// { team: 'A', score: 12, name: 'Anna' },
// { team: 'A', score: 12, name: 'Bea' },
// { team: 'A', score: 10, name: 'Chris' },
// ]Implementation Notes
- Throws
TypeErrorif the first argument is not an array. - Uses native array sorting and returns a cloned array (
[...array]) to keep input immutable. - Uses
compare()in selector mode andcompareBy()in object-selector mode.