使用jq从数组中的对象获取值的总和

时间:2017-05-25 03:45:11

标签: json count jq

我试图获取数组中特定值的总金额。 输入类似于

[{
    "name": "mars",
    "runner":  [
        {
        "foo": null,
        "idle": true
        },
        {
        "foo": null,
        "idle": true
        },
        {
        "foo": null,
        "idle": false
        }

    ],
        "name": "june",
        "runner": [
        {
        "foo": null,
        "idle": true
        },
        {
        "foo": null,
        "idle": true
        },
        {
        "foo": null,
        "idle": true
        }
    ]
}]

所需的输出

  

[{" name" :"火星","闲置" :2"},{" name" :" 6月","空闲" :1"}]

我尝试使用select和map,但我并不清楚jq是如何工作的,例如,我尝试了以下查询

jq  ' .[] | select(.runner[].idle == true) | {name: .name}'

结果是

  

{" nome":" mars" } {" nome":"火星" } {" nome":" june" } {
  " nome":" june" } {" nome":" june" }

(6月份为3倍,火星为2倍)我可以继续解析json并得到我想要的结果,但它看起来并不正确。

1 个答案:

答案 0 :(得分:2)

您的输入数据似乎与您的发布完全一致。我假设你的意思是:

[{"name":"mars",
  "runner":[{"foo":null,"idle":true},{"foo":null,"idle":true},{"foo":null,"idle":false}]},
 {"name":"june",
  "runner":[{"foo":null,"idle":true},{"foo":null,"idle":true},{"foo":null,"idle":true}]}]

长度

合理的方法是依靠内置的length函数:

map( { name, idle: (.runner | map(select(.idle)) | length)} )

计数

更好(例如更有效)的解决方案是定义一个可以计算的函数:

def count(s): reduce s as $i (0; .+1); 

此处s是生成值流的任何过滤器。然后可以按如下方式编写解决问题的方法:

map( {name, idle: count(.runner[] | select(.idle))} )

输出

两种情况下的输出:

[
  {
    "name": "mars",
    "idle": 2
  },
  {
    "name": "june",
    "idle": 3
  }
]