一尘不染

如何在jq中的地图数组中求和?

json

给定以下形式的JSON流:

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

我想对每个对象中的值求和并输出一个对象,即:

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

我猜想这可能需要将上述对象列表展平为[name, value]成对的数组,然后使用来求和,reduce但使用语法的文档却很reduce糟糕。


阅读 273

收藏
2020-07-27

共1个答案

一尘不染

除非您的jq拥有inputs,否则您将不得不使用该-s标志来吞噬对象。然后,您必须进行大量的操作:

  1. 每个对象都需要映射到键/值对
  2. 将对展平为单个数组
  3. 通过密钥将对分组
  4. 将每个累积值的组映射到单个键/值对
  5. 将对映射回对象
    map(to_entries)
        | add
        | group_by(.key)
        | map({
              key: .[0].key,
              value: map(.value) | add
          })
        | from_entries

使用jq 1.5,可以大大改善这一点:您可以消除拖尾的感觉,而直接阅读inputs

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

由于我们只是累加每个对象中的所有值,因此遍历所有输入的键/值对并将它们加起来会更容易。

2020-07-27