Skip to main content

orderBy()

orderBy<T>(array, iteratees, orders?): T[]

Sorts an array by multiple criteria with configurable sort orders.

WHY WRAPPING NATIVE?

We prefer to wrap this method to ensure Immutability instead of the native sort which mutates. See Design Philosophy

WHY DUAL ITERATEE SIGNATURE?

Unlike other Arkhe functions that use function-only iteratees, orderBy accepts both keyof T and functions. This exception exists because multi-criteria sorting (often 3+ fields) benefits significantly from the ergonomic ['age', 'score', 'name'] syntax over the verbose [u => u.age, u => u.score, u => u.name]. The runtime cost of typeof checks is O(k) where k is the number of criteria (typically 1-3), negligible compared to the O(n log n) sort.

STABLE SORT

elements with equal values maintain their relative order.


Type Parametersโ€‹

T: Tโ€‹

The type of elements in the array.


Parametersโ€‹

array: readonly T[]โ€‹

The array to sort.

iteratees: (keyof T | (item) => unknown)[]โ€‹

Property keys or functions to extract sort values.

orders?: SortOrder[]โ€‹

Sort orders for each iteratee. Defaults to 'asc' for all.


Returns: T[]โ€‹

A new sorted array.


Sinceโ€‹

2.0.0


Performanceโ€‹

O(n log n) time, O(n) space. Pre-computes criteria to avoid repeated function calls during sort.


Also known asโ€‹

orderBy (Lodash, es-toolkit) ยท sort (Radashi, Modern Dash) ยท sortBy (Remeda) ยท sortWith (Ramda, Effect) ยท โŒ (Antfu)


Exampleโ€‹

const users = [
{ name: 'John', age: 25, score: 85 },
{ name: 'Bob', age: 25, score: 80 },
{ name: 'Jane', age: 30, score: 90 }
];

// Using property keys (ergonomic)
orderBy(users, ['age', 'score'], ['asc', 'desc']);
// => [{ name: 'John', age: 25, score: 85 }, { name: 'Bob', age: 25, score: 80 }, { name: 'Jane', age: 30, score: 90 }]

// Using functions (for computed values)
orderBy(users, [u => u.age, u => u.name.length], ['asc', 'desc']);

How it works?โ€‹

Sorts by multiple criteria with configurable sort orders (asc/desc). Unlike native sort(), returns a new array (immutable).

Multi-criteria logicโ€‹


Use Casesโ€‹

Sort by multiple criteria ๐Ÿ“Œโ€‹

Organize data with primary and secondary sort keys. Perfect for data tables, leaderboards, or search results.

const employees = [
{ name: "Alice", department: "Engineering", salary: 95000 },
{ name: "Bob", department: "Sales", salary: 78000 },
{ name: "Charlie", department: "Engineering", salary: 120000 },
{ name: "Diana", department: "Engineering", salary: 95000 },
];

const sorted = orderBy(employees, ["department", "salary"], ["asc", "desc"]);
// => [Charlie (Eng, 120k), Alice (Eng, 95k), Diana (Eng, 95k), Bob (Sales, 78k)]

Rank products by rating and reviews ๐Ÿ“Œโ€‹

Create leaderboards with multiple ranking factors. Ideal for e-commerce listings or recommendation engines.

const products = [
{ name: "Pro Keyboard", rating: 4.5, reviews: 1250 },
{ name: "Basic Keyboard", rating: 4.2, reviews: 3400 },
{ name: "Gaming Keyboard", rating: 4.5, reviews: 890 },
];

const ranked = orderBy(products, ["rating", "reviews"], ["desc", "desc"]);
// => [Pro Keyboard, Gaming Keyboard, Basic Keyboard]

Sort with custom iterateeโ€‹

Use functions for computed sort values. Useful for complex business logic or derived fields.

const tasks = [
{ title: "Bug fix", priority: "high", dueDate: new Date("2024-01-20") },
{ title: "Feature", priority: "low", dueDate: new Date("2024-01-18") },
{ title: "Refactor", priority: "high", dueDate: new Date("2024-01-15") },
];

const priorityOrder = { high: 0, medium: 1, low: 2 };

const sorted = orderBy(
tasks,
[(t) => priorityOrder[t.priority], (t) => t.dueDate.getTime()],
["asc", "asc"]
);
// => [Refactor (high, Jan 15), Bug fix (high, Jan 20), Feature (low, Jan 18)]

Real-time leaderboard for sports competitionsโ€‹

Rank athletes or teams in real-time during live competitions. Essential for sports apps, esports tournaments, and fitness challenges.

const athletes = [
{ name: "Usain Bolt", time: 9.58, country: "JAM", personalBest: 9.58 },
{ name: "Tyson Gay", time: 9.69, country: "USA", personalBest: 9.69 },
{ name: "Yohan Blake", time: 9.75, country: "JAM", personalBest: 9.69 },
{ name: "Justin Gatlin", time: 9.74, country: "USA", personalBest: 9.74 },
];

// Rank by finish time (ascending), then by personal best
const leaderboard = orderBy(
athletes,
["time", "personalBest"],
["asc", "asc"]
);
// => [Bolt (9.58), Gay (9.69), Gatlin (9.74), Blake (9.75)]

// For live updates, re-sort as times come in
const updateLeaderboard = (newResult) => {
athletes.push(newResult);
return orderBy(athletes, ["time"], ["asc"]);
};

Sort notifications by unread status then by dateโ€‹

Display unread notifications first, then sort by most recent. Universal pattern for any app with a notification center or inbox.

const notifications = [
{ id: 1, message: "New comment", read: true, date: "2025-06-10T09:00:00Z" },
{ id: 2, message: "Mention in #general", read: false, date: "2025-06-09T14:00:00Z" },
{ id: 3, message: "PR approved", read: false, date: "2025-06-10T11:00:00Z" },
{ id: 4, message: "Build failed", read: true, date: "2025-06-10T10:00:00Z" },
];

const sorted = orderBy(
notifications,
[(n) => (n.read ? 1 : 0), "date"],
["asc", "desc"]
);
// => [PR approved (unread, Jun 10), Mention (unread, Jun 9), Build failed (read), New comment (read)]

SortOrderโ€‹

Type

SortOrder = "asc" | "desc"

Sort order type for orderBy function.


Sinceโ€‹

2.0.0