JQ聚合和交叉表

时间:2015-06-07 07:20:35

标签: jq

我有一些数据:

[
  {
    "count": 4,
    "trial_status": "Follow up",
    "date": "2015-06-06"
  },
  {
    "count": 3,
    "trial_status": "Hold",
    "date": "2015-06-06"
  },
  {
    "count": 2,
    "trial_status": "Trial",
    "date": "2015-06-06"
  },
  {
    "count": 1,
    "trial_status": "Trial + Confirm",
    "date": "2015-06-06"
  }....

我想转换为

{"2015-06-06": {"Trial + Confirm": 1, "Follow Up": 4, "Hold": 3, "Trial": 2}}

我的任何方法都没有取得很大进展,所以非常感谢一些帮助。

3 个答案:

答案 0 :(得分:2)

这应该有效:

group_by(.date) | map({
    key: .[0].date,
    value: map({
        key: .trial_status,
        value: .count
    }) | from_entries
}) | from_entries

关键是使用from_entries来构建映射。 这是你可以按名称设置"属性" /键的唯一方法。你只需要生成构成对象的键/值对。

Santiago指出,您可以使用特殊语法按名称动态设置属性。这也可以。

group_by(.date) | map({
    (.[0].date): map({
        (.trial_status): .count
    }) | add
}) | add

答案 1 :(得分:2)

以下是使用reducedestructuring variable bindingsetpath

的解决方案
reduce .[] as {count:$c, trial_status:$s, date:$d} (
  {}
; setpath([$d, $s]; $c)
)

如果此过滤器位于filter.jqdata.json包含示例数据,则命令

$ jq -M -f filter.jq data.json

产生

{
  "2015-06-06": {
    "Follow up": 4,
    "Hold": 3,
    "Trial": 2,
    "Trial + Confirm": 1
  }
}

答案 2 :(得分:0)

如果您因为地图内的地图而发现头部旋转,或者您更喜欢直接进近(在这种情况下至少也恰好也快速而简单),请考虑使用reduce,如下所示: reduce .[] as $o ({}; . + {($o.date): (.[$o.date] + {($o.trial_status): $o.count} )})

感谢jq的null语义,这可以简化并缩短为: reduce .[] as $o ({}; .[$o.date] += { ($o.trial_status): $o.count } )