How to reconstruct array data?

I have this data:

{
  "data": [
    {
      "a": 11,
      "b": 12,
      "c": 13
    },
    {
      "a": 21,
      "b": 22,
      "c": 23
    },
    {
      "a": 31,
      "b": 32,
      "c": 33
    }
  ]
}

I want to collate it into arrays based on the key names like this:

{
  "data": [
    {
      "a": [
        11,
        21,
        31
      ]
    },
    {
      "b": [
        12,
        22,
        32
      ]
    },
    {
      "c": [
        13,
        23,
        33
      ]
    }
  ]
}

For this example we can assume that each element of the original array has the same set of keys, just different values for them.

This jq code can do it for select keys:

jq '(.data[0]|keys_unsorted) as $keys | { ($keys[2]): [.data[]|.[$keys[2]]] }' data.json
{
  "c": [
    13,
    23,
    33
  ]
}

How do I do this for all keys?

>Solution :

One way would be using to_entries to access the keys, then group_by for the grouping, and map to construct the final structure:

.data |= (map(to_entries[]) | group_by(.key) | map({(first.key): map(.value)}))
{
  "data": [
    {
      "a": [
        11,
        21,
        31
      ]
    },
    {
      "b": [
        12,
        22,
        32
      ]
    },
    {
      "c": [
        13,
        23,
        33
      ]
    }
  ]
}

Suggestion: Instead of having an array of objects with a single field, you could instead build one object containing all fields:

.data |= reduce (.[] | to_entries[]) as {$key, $value} ({}; .[$key] += [$value])
{
  "data": {
    "a": [
      11,
      21,
      31
    ],
    "b": [
      12,
      22,
      32
    ],
    "c": [
      13,
      23,
      33
    ]
  }
}

Leave a Reply