skip to Main Content

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.

2

Answers


  1. 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)))'
    
    Login or Signup to reply.
  2. 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
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search