0

I have a JSON array like this:

[
  {
    "name": "Bo",
    "type": "dog"
  },
  {
    "name": "Roxer",
    "type": "dog"
  },
  {
    "name": "Paws",
    "type": "cat"
  }
]

I'm trying to convert it to an object keyed by type, like this:

{
  "dog": [
    {
      "name": "Bo",
      "type": "dog"
    },
    {
      "name": "Roxer",
      "type": "dog"
    }
  ],
  "cat": [
    {
      "name": "Paws",
      "type": "cat"
    }
  ]
}

I found this answer which uses map, but it assumes the type is unique and doesn't convert it to an array:

reduce .[] as $i ({}; .[$i.type] = $i)

The first time a value is inserted, it should be inserted as [$i]. Any other time, it should append [] + $i.

nathancahill
  • 10,452
  • 9
  • 51
  • 91

2 Answers2

4

Your case differs from the one you found because you are putting objects into an array. Try this modification of Jeff Mercado's solution.

jq 'reduce .[] as $i ({}; .[$i.type] += [$i])'
user197693
  • 1,935
  • 10
  • 8
1

Another possible way using group_by() on the .type field and then create the final result with .type as the key

jq 'group_by(.type)[] | { (.[0].type) : . }'

The only difference in this approach, is group_by() does a sort by the .type field before producing the result, so the order of keys will be different.

Inian
  • 80,270
  • 14
  • 142
  • 161