jq中的累计金额

时间:2015-05-11 15:54:37

标签: jq

我在数组中有一系列[timestamp, count]对,并希望使用jq计算每个时间戳的累积和。我怎么能这样做?

这是一个示例数据集:

[
  [1431047957699, 1],
  [1431047958269, 1],
  [1431047958901, 1],
  [1431047959147, -1],
  [1431047960164, 1]
]

预期结果:

[1431047957699, 1],
[1431047958269, 2],
[1431047958901, 3],
[1431047959147, 2],
[1431047960164, 3]

是否可以使用jq执行此操作?

2 个答案:

答案 0 :(得分:2)

采用功能性方法并创建一个更新函数,该函数将使用累积总和创建更新值。

def accumulate(acc):
    select(length > 0) |
    (.[0][1] + acc) as $next |
    (.[0] | .[1] = $next), (.[1:] | accumulate($next))
    ;
[accumulate(0)]

在这里,我们将数组分成“head”和“tail”,用当前总和更新头部并递归更新尾部。结果将重新放回新数组中。

答案 1 :(得分:2)

以下内容非常通用(例如,它可以与对象数组一起使用):

def accumulate(f):
  reduce .[1:][] as $row
    ([.[0]];
     . as $x
     | $x + [ $row | (f = ($x | .[length-1] | f) + ($row|f)  ) ] );

accumulate(.[1])

如果您使用的是最新版本的jq,那么“$ x |  。[length-1]“可以简化为”$ x [-1]“。

使用foreach的解决方案

如果你的jq有foreach,那么可以使用以下变体。如果需要值流而不是数组,那将是特别合适的。

def accumulates(f):
  foreach .[] as $row
    (0;
     . + ($row | f) ;
     . as $x | $row | (f = $x));

用法:

对于流:accumulates(.[0])

对于数组:[accumulates(.[0])