从JSON中获取最大值的方法是什么?

8
有一个像这样的json文件:
[
{
    "createdAt": 1548729542000,
    "platform": "foo"
},
{
    "createdAt": 1548759398000,
    "platform": "foo"
},
{
    "createdAt": 1548912360000,
    "platform": "foo"
},
{
    "createdAt": 1548904550000,
    "platform": "bar"
}
]

现在我想通过使用 jq 获取 foo 平台的最大 createdAt 值,如何实现?

jq '.[] | select(.platform=="foo") | .createdAt | max' foo.json
jq: error (at <stdin>:17): number (1548729542000) and number (1548729542000) cannot be iterated over

jq '.[] | select(.platform=="foo") | max_by(.createdAt)' foo.json
jq: error (at <stdin>:17): Cannot index number with string "createdAt"
exit status 5
2个回答

18

max 函数期望输入一个数组。

$ jq 'map(select(.platform == "foo") .createdAt) | max' file
1548912360000

如果能够更详细地解释答案会更好。如果我使用示例 JSON 和 jq '.[] | select(.platform=="foo") | .createdAt',那么它显然会输出行。map 接受一个数组并输出一个新数组。所以我不清楚为什么 map 在这里起作用... 好吧,它能够正常工作表明原始查询没有生成一个数组,但我不理解其中的区别。 - Anentropic
@Anentropic 不同之处在于 .[] | select(.platform=="foo") | .createdAt 产生数字,而 map(select(.platform=="foo") | .createdAt) 产生一个数组。当你执行 1, 2, 3 | max 时,max 应用于每个数字(并失败,因为它们不是数组);当你执行 [1, 2, 3] | max 时,它应用于整个数组(并返回具有最大值的元素)。 - oguz ismail
2
谢谢,我一直在通过试错来解决它...我发现返回行(不是数组本身,但每行可能是一个数组)和将行收集到数组中并返回它之间的区别令人困惑。不过你的答案帮了我很多。 - Anentropic

2

一种方法是先进行选择,然后使用数组导向的内置函数maxmax_by来找到最大值,例如:


map(select(.platform=="foo"))
| max_by(.createdAt)
| .createdAt

然而,这种方法并不是非常令人满意,因为它需要比严格必要的更多的空间。对于大型数组,max_by 的流版本会更好。

最大值

def max_by(s; f):
  reduce s as $s (null;
    if . == null then {s: $s, m: ($s|f)}
    else  ($s|f) as $m
    | if $m > .m then {s: $s, m: $m} else . end
    end)
  | .s ;

max_by(.[] | select(.platform=="foo"); .createdAt)
| .createdAt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接