sortBy
Returns a new array sorted by the result of a selector function. Preserves the original array.
1/**
2 * Returns a new array sorted by the result of a selector function.
3 * Preserves the original array.
4 *
5 * @param arr - The input array to sort.
6 * @param fn - A selector function that returns a string or number to sort by.
7 * @returns A new sorted array based on the selector output.
8 */
9export function sortBy<T>(arr: T[], fn: (item: T) => number | string): T[] {
10 return [...arr].sort((a, b) => {
11 const aKey = fn(a);
12 const bKey = fn(b);
13 if (aKey < bKey) return -1;
14 if (aKey > bKey) return 1;
15 return 0;
16 });
17}
Flexible sorting logic
Supports any string or numeric sorting strategy through the provided selector function, enabling sorting by name, length, date, priority, etc.
Non-mutating behavior
Creates a shallow copy before sorting, preserving the integrity of the original array — a safe and functional programming practice.
Stable and predictable
Uses standard comparison logic, maintaining consistent results across different JavaScript engines for basic types.
Type-safe and generic
Fully typed with generics to ensure proper type inference and type checking in TypeScript projects.
Compact and readable
Clear implementation with minimal overhead, ideal for inline use or integration into larger pipelines.
Tests | Examples
1test('sortBy - by string length', () => {
2 expect(sortBy(['ccc', 'a', 'bb'], str => str.length)).toEqual(['a', 'bb', 'ccc']);
3});
4
5test('sortBy - by numeric property', () => {
6 const data = [{ id: 3 }, { id: 1 }, { id: 2 }];
7 expect(sortBy(data, obj => obj.id)).toEqual([{ id: 1 }, { id: 2 }, { id: 3 }]);
8});
9
10test('sortBy - by alphabetical order', () => {
11 expect(sortBy(['banana', 'apple', 'cherry'], s => s)).toEqual(['apple', 'banana', 'cherry']);
12});
13
14test('sortBy - with duplicate keys', () => {
15 const data = [{ v: 2 }, { v: 1 }, { v: 2 }];
16 expect(sortBy(data, x => x.v)).toEqual([{ v: 1 }, { v: 2 }, { v: 2 }]);
17});
18
19test('sortBy - empty array', () => {
20 expect(sortBy([], x => x)).toEqual([]);
21});
Common Use Cases
UI and display logic
Sorting lists of items by name, price, score, or timestamps in tables, dropdowns, or card grids.
Data transformation pipelines
Used as part of functional chains (e.g.,
filter → map → sortBy → slice
) to prepare datasets for rendering or export.Report generation
Ordering metrics or summaries by numeric value or category label.
Custom logic sorting
For example, sorting files by extension length, names by vowel count, or objects by computed priority.