Reference · Lists

group_by

signature
group_by(list | null, fn) -> map

What it does

A map from each key to the list of items with that key, the key being what the function gives for the item. The keys are in the order they first appear, and so are the items inside each group. A map's keys are text, so the key is written as text: 1 and "1" are one key. null counts as an empty list and gives {}.

Examples

let orders = [{ id: 1, status: "paid" }, { id: 2, status: "open" }, { id: 3, status: "paid" }]print(group_by(orders, (o) => o.status))let by_status = group_by(orders, (o) => o.status)print(keys(by_status), by_status.paid | map((o) => o.id))for [status, os] in by_status {    print(status, len(os))}print(group_by([1, 2, 3, 4, 5], (x) => x % 2 == 0 ? "even" : "odd"))
output
{ paid: [{ id: 1, status: "paid" }, { id: 3, status: "paid" }], open: [{ id: 2, status: "open" }] }["paid", "open"] [1, 3]paid 2open 1{ odd: [1, 3, 5], even: [2, 4] }

Edge cases

print(group_by([], (x) => x), group_by(null, (x) => x))print(group_by(["pear", "fig", "apple"], len))print(group_by([1, "1", 1.0, 2], (x) => x), group_by([3, 1, 2], (x) => x > 1))print(group_by([dec("1.50"), dec("1.5")], (x) => x))let g = group_by(["a"], (x) => x)print(g.b, get(g, "b", []))print(group_by(["b", "a", "b"], (x) => x) | keys | sort)print(group_by(["1", "x"], (s) => int(s)))
output
{} {}{ "4": ["pear"], "3": ["fig"], "5": ["apple"] }{ "1": [1, "1"], "1.0": [1.0], "2": [2] } { true: [3, 2], false: [1] }{ "1.5": [1.50m, 1.5m] }null []["a", "b"]err("not an int: \"x\"")

Errors

A first argument that is not a list or null, or a second that is not a function, is a runtime error, not an error value. A runtime error inside the function stops the request; an error value it gives is given back (above).

this one fails
print(group_by("ab", (c) => c))
output
line 1: `group_by` expects a list as argument 1, got str
this one fails
print(group_by([1, 2]))
output
line 1: `group_by` expects a function as argument 2, got nothing

Chaining

In a pipeline the list comes first and the key function is the only argument: xs | group_by(f). Walk the map with for [key, items] in ..., or keys and values it, to total each group.

let orders = [{ status: "paid", total: 10 }, { status: "open", total: 5 }, { status: "paid", total: 7 }]for [status, os] in orders | group_by((o) => o.status) {    print(status, os | map((o) => o.total) | sum)}print(orders | group_by((o) => o.status) | keys)print(orders | group_by((o) => o.status) | values | map(len))
output
paid 17open 5["paid", "open"][2, 1]

See also

count, unique, sort_by, keys, values, get, join_on

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

Thread 0 posts

On group_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