Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I sum the values in an array of maps in jq?

Tags:

json

key

sum

jq

Given a JSON stream of the following form:

{ "a": 10, "b": 11 } { "a": 20, "b": 21 } { "a": 30, "b": 31 } 

I would like to sum the values in each of the objects and output a single object, namely:

{ "a": 60, "b": 63 } 

I'm guessing this will probably require flattening the above list of objects into a an array of [name, value] pairs and then summing the values using reduce but the documentation of the syntax for using reduce is woeful.

like image 786
Alan Burlison Avatar asked Feb 12 '15 17:02

Alan Burlison


People also ask

How do you find the sum of an array of objects?

To sum a property in an array of objects:Initialize a sum variable, using the let keyword and set it to 0 . Call the forEach() method to iterate over the array. On each iteration, increment the sum variable with the value of the object.

What is JQ expression?

A jq program is a "filter": it takes an input, and produces an output. There are a lot of builtin filters for extracting a particular field of an object, or converting a number to a string, or various other standard tasks.


1 Answers

Unless your jq has inputs, you will have to slurp the objects up using the -s flag. Then you'll have to do a fair amount of manipulation:

  1. Each of the objects needs to be mapped out to key/value pairs
  2. Flatten the pairs to a single array
  3. Group up the pairs by key
  4. Map out each group accumulating the values to a single key/value pair
  5. Map the pairs back to an object
map(to_entries)     | add     | group_by(.key)     | map({           key: .[0].key,           value: map(.value) | add       })     | from_entries 

With jq 1.5, this could be greatly improved: You can do away with slurping and just read the inputs directly.

$ jq -n ' reduce (inputs | to_entries[]) as {$key,$value} ({}; .[$key] += $value) ' input.json 

Since we're simply accumulating all the values in each of the objects, it'll be easier to just run through the key/value pairs of all the inputs, and add them all up.

like image 194
Jeff Mercado Avatar answered Oct 04 '22 10:10

Jeff Mercado