jq · lesson 18 of 32 · Aggregation
Sort, group & unique
sort_by(key) orders an array, group_by(key) buckets its elements into arrays, and unique drops duplicates. flatten merges nested arrays.
Examples
Example 1Sort by a field
Document
{
"team": "Platform",
"office": { "city": "Berlin", "floor": 3 },
"members": [
{ "name": "Ada", "age": 36, "role": "lead", "active": true,
"email": "[email protected]", "skills": ["rust", "sql"] },
{ "name": "Linus", "age": 28, "role": "dev", "active": true,
"email": null, "skills": ["c", "shell"] },
{ "name": "Grace", "age": 45, "role": "dev", "active": false,
"skills": ["cobol"] },
{ "name": "Alan", "age": 41, "role": "qa", "active": true,
"email": "[email protected]", "skills": [] }
]
}Query
.members | sort_by(.age) | map(.name)
sort_by(.age)Order the members by age, youngest first.map(.name)Keep just the names.
Result
["Linus","Ada","Alan","Grace"]
Example 2Group by a field
Document
{
"team": "Platform",
"office": { "city": "Berlin", "floor": 3 },
"members": [
{ "name": "Ada", "age": 36, "role": "lead", "active": true,
"email": "[email protected]", "skills": ["rust", "sql"] },
{ "name": "Linus", "age": 28, "role": "dev", "active": true,
"email": null, "skills": ["c", "shell"] },
{ "name": "Grace", "age": 45, "role": "dev", "active": false,
"skills": ["cobol"] },
{ "name": "Alan", "age": 41, "role": "qa", "active": true,
"email": "[email protected]", "skills": [] }
]
}Query
.members | group_by(.role) | map({role: .[0].role, names: map(.name)})
group_by(.role)An array of arrays: one group per distinct role.map(For each group…{role: .[0].role, names: map(.name)}…build a summary: the role (taken from the group's first member) and every name in it.
Result
[
{"role":"dev","names":["Linus","Grace"]},
{"role":"lead","names":["Ada"]},
{"role":"qa","names":["Alan"]}
]Example 3Flatten and de-duplicate
Document
{
"team": "Platform",
"office": { "city": "Berlin", "floor": 3 },
"members": [
{ "name": "Ada", "age": 36, "role": "lead", "active": true,
"email": "[email protected]", "skills": ["rust", "sql"] },
{ "name": "Linus", "age": 28, "role": "dev", "active": true,
"email": null, "skills": ["c", "shell"] },
{ "name": "Grace", "age": 45, "role": "dev", "active": false,
"skills": ["cobol"] },
{ "name": "Alan", "age": 41, "role": "qa", "active": true,
"email": "[email protected]", "skills": [] }
]
}Query
.members | map(.skills) | flatten | unique
map(.skills)An array of skill arrays.flattenMerge the nested arrays into one flat array.uniqueSort it and drop duplicates.
Result
["c","cobol","rust","shell","sql"]
Good to know
reverseflips an array, sosort_by(.age) | reversesorts oldest first.unique_by(.role)keeps one element per distinct role.