jq:为具有相同ID的所有对象添加特定键的值

时间:2017-09-18 19:39:07

标签: json jq

我有一个包含大量对象的JSON数组,它看起来像这样:

[
{"ID":"A","VALUE":12,"TYPE":"single"},
{"ID":"A","VALUE":17,"TYPE":"single"},
{"ID":"A","VALUE":-7,"TYPE":"single"},

{"ID":"B","VALUE":35,"TYPE":"single"},
{"ID":"B","VALUE":10,"TYPE":"single"},
{"ID":"B","VALUE":15,"TYPE":"single"},

{"ID":"C","VALUE":0,"TYPE":"single"},
{"ID":"C","VALUE":13,"TYPE":"single"},
{"ID":"C","VALUE":20.5,"TYPE":"single"}
]

现在我想为每个ID添加所有值,并使用如下结果创建新对象:

{"ID":"A","VALUE":22,"TYPE":"total"},
{"ID":"B","VALUE":60,"TYPE":"total"},
{"ID":"C","VALUE":23.5,"TYPE":"total"}

此外,应将结果对象添加到初始数组中。

我对jq很新,所以我做了一些研究。事实上,我知道如何获得ID的总数:

[.[] | select(."ID"=="A").VALUE]|add

-> 22

以及如何创建新对象:

.[] | {ID: .ID, VALUE: .VALUE, TYPE: "total"}

但是如何从这里获得我想要的格式?有一个循环?

谢谢!

2 个答案:

答案 0 :(得分:3)

这是一个解决方案,它使用reduce来计算总数,生成指定格式的对象并将它们添加到原始输入数组中:

 . + [
     reduce .[] as $r ({}; .[$r["ID"]] += $r["VALUE"])
   | keys[] as $id
   | {ID:$id, VALUE:.[$id], TYPE:"total"}
 ]

请注意,使用C的示例数据计算的值为33.5,我认为这是正确的。

答案 1 :(得分:2)

您可以按ID对它们进行分组,然后将它们聚合到新对象中。然后将其与现有的项目数组合。

[.[], (group_by(.ID)[] | { ID: .[0].ID, VALUE: map(.VALUE)|add, TYPE: "total" })]