Reference · Lists

sort_by

signature
sort_by(list | null, fn) -> list

What it does

The items in ascending order of a key, as a new list. The function takes one argument, the item, and gives its key: a number or a string. The sort is stable: items with equal keys keep their order. There is no descending flag; negate a numeric key or reverse the result. null counts as an empty list.

f may give a list, to sort by several keys: sort_by(rows, (r) => [r.a, r.b]). Lists compare item by item.

Examples

let people = [{ name: "Cy", age: 30 }, { name: "Ann", age: 25 }, { name: "Bo", age: 30 }]print(sort_by(people, (p) => p.age))print(sort_by(people, (p) => p.name) | map((p) => p.name))print(sort_by(["bb", "a", "ccc"], len))print(sort_by(["Bob", "alice", "Carl"], lower))
output
[{ name: "Ann", age: 25 }, { name: "Cy", age: 30 }, { name: "Bo", age: 30 }]["Ann", "Bo", "Cy"]["a", "bb", "ccc"]["alice", "Bob", "Carl"]

Edge cases

print(sort_by([], (x) => x), sort_by(null, (x) => x))let people = [{ name: "Cy", age: 30 }, { name: "Ann", age: 25 }, { name: "Bo", age: 30 }]print(sort_by(people, (p) => p.age) | map((p) => p.name))print(sort_by(people, (p) => -p.age) | map((p) => p.name))print(sort_by(people, (p) => p.age) | reverse | map((p) => p.name))print(sort_by(people, (p) => p.name) | sort_by((p) => p.age) | map((p) => p.name))
output
[] []["Ann", "Cy", "Bo"]["Cy", "Bo", "Ann"]["Bo", "Cy", "Ann"]["Ann", "Bo", "Cy"]

Errors

A list that is not a list or null, or a key function that is not a function, is a runtime error, not an error value. Keys that do not order are a runtime error too: a missing field gives null as the key, and a string key beside a number is as bad.

this one fails
print(sort_by([{ a: 1 }, { b: 2 }], (m) => m.a))
output
line 1: `sort_by` cannot compare null with int
this one fails
print(sort_by([{ n: "1" }, { n: 2 }], (m) => m.n))
output
line 1: `sort_by` cannot compare int with str
this one fails
print(sort_by([1, 2], 3))
output
line 1: `sort_by` expects a function as argument 2, got int

Chaining

In a pipeline the list comes first and the key function is the only argument: xs | sort_by(f). It takes the place of a comparator: for the item with the smallest or largest key, take the first or the last.

let orders = [{ id: 1, total: 30 }, { id: 2, total: 12 }, { id: 3, total: 21 }]print(orders | sort_by((o) => o.total) | map((o) => o.id))print(orders | sort_by((o) => o.total) | first)print(orders | sort_by((o) => o.total) | reverse | take(2) | map((o) => o.id))
output
[2, 3, 1]{ id: 2, total: 12 }[1, 3]

See also

sort, reverse, min, max, group_by, vec.argsort

Thread
7Useful? Like it, or add to its thread below.

Thread 0 posts

On sort_by(): questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.

    Edit this page on GitHub · every example's output was made by running it (tools/refcheck.mjs) · questions on Discord or r/quillo