Reputation: 356
Given this JSON data in the file data.json
:
[
{ "id": 1, "entityType": "cat" },
{ "id": 2, "entityType": "dog" },
{ "id": 3, "entityType": "bird" },
{ "id": 4, "entityType": "cat" }
]
How would return an array sorted by some non-alphabetic arbitrary order (e.g dogs, birds and then cats)?
I've tried various permutations along the lines of:
jq --argjson order '["dog", "bird", "cat"]' '. | sort_by( index($order[], .entityType) )' data.json
but without any joy.
Upvotes: 1
Views: 71
Reputation: 116957
If the order is defined by an array, then for efficiency it would typically be worthwhile converting the array to a dictionary along the lines suggested by @choroba:
< input.json jq --argjson order '["dog", "bird", "cat"]' '
INDEX( $order | to_entries[]; .value ) as $dict
| sort_by( $dict[.entityType] )
'
Upvotes: 0
Reputation: 242123
It's easier (and faster) to use an object for the order:
jq --argjson order '{"dog":0, "bird":1, "cat":2}' \
'. | sort_by($order[.entityType])'
But if you insist:
jq --argjson order '["dog", "bird", "cat"]' \
'. | sort_by(.entityType as $type | ($order | index($type)))'
Upvotes: 3
Reputation: 36391
If you want to keep your order
argument an array, sort by turning it into an implicit boolean array of matches. Note that false
will be ordered before true
, so use !=
to "mismatch" the items.
jq --argjson order '["dog", "bird", "cat"]' 'sort_by(.entityType != $order[])'
[
{
"id": 2,
"entityType": "dog"
},
{
"id": 3,
"entityType": "bird"
},
{
"id": 1,
"entityType": "cat"
},
{
"id": 4,
"entityType": "cat"
}
]
Alternatively, provide the order as single arguments using the --args
option and the $ARGS.positional
array:
jq 'sort_by(.entityType != $ARGS.positional[])' data.json --args dog bird cat
Upvotes: 1