Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

json - How do I sum the values in an array of maps in 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...