Skip to content
VersionSize

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 TypeError if 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 and compareBy() in object-selector mode.

See Also

  • compareBy: Build comparator functions for object sorting.
  • group: Organize elements into collections.