BrandonH
BrandonH

Reputation: 41

Reshape a jq array with summarized data

New to jq but I've managed to group a load of data which I would now like summarized in a different format. Original data after group by and mapping:

[
  {
    "Agents": "a",
    "Count": 1
  },
  {
    "Agents": "b",
    "Count": 50
  },
  {
    "Agents": "c",
    "Count": 25
  },
  {
    "Agents": "d",
    "Count": 1
  },
  {
    "Agents": "e",
    "Count": 4
  },
  {
    "Agents": "f",
    "Count": 4
  },
  {
    "Agents": "g",
    "Count": 4
  }
]

and I would like this output:

{
  "Count": 7,
  "Agents": {
    "a": 1,
    "b": 50,
    "c": 25,
    "d": 1,
    "e": 4,
    "f": 4,
    "g": 4
  }
}

How exactly might I do this in jq please because it requires mapping the values as field names?

Upvotes: 3

Views: 1284

Answers (2)

Inian
Inian

Reputation: 85550

Another variant using reduce would be to do. The reduce expression takes the array as input and puts the key as the Agents and the value as its corresponding Count value.

jq '{ Count: length, Agents: (reduce .[] as $d ({}; .[$d.Agents] = $d.Count)) }'

The Object Value Iterator .[] used to construct the JSON. For a given .["a"], it returns "a" which is how the keys are constructed in the final JSON.

Upvotes: 4

chepner
chepner

Reputation: 530940

Use map to create an input for from_entries:

map({key: .Agents, value: .Count}) | {Count: length, Agents: from_entries}

map produces a list of objects like [{"key": "a", "value": 1}, ...]. from_entries turns that into a single object {"a": 1, ...}. In the final object, both length and from_entries get the same array as input, and their outputs are used to create the final object with Count and Agents keys.

Upvotes: 2

Related Questions