jq:添加嵌套数字?

问题描述 投票:2回答:4

jq中,如何添加嵌套在流对象中的数字?

示例:

{"game":
    {"player1": {"score": 2}}}
{"game":
    {"player1": {"score": 4}}}

我可以使用两个jq呼叫添加这些数字:

$ cat foo.json | jq '.game.player1.score' | jq --slurp 'add'
6

如何通过一个jq呼叫来完成?

而且,如何分别增加两个不同玩家的得分?

{"game":
    {"player1": {"score": 2},
     "player2": {"score": 20}}}
{"game": 
    {"player1": {"score": 4},
     "player2": {"score": 40}}}

$ cat foo.json | jq '???'
{"player1": 6, "player2": 60} 
json jq addition
4个回答
1
投票

[首先,这是@OguzIsmail针对第一个问题的第一个解决方案的变体。它用于验证通用函数的有效性:

   def sigma(s): reduce s as $x (0; .+$x);

有了这个,并使用-n命令行选项,给定问题的解决方案很简单:

    sigma(inputs.game.player1.score)

第二个问题

具有相同的通用性:

def sigmas(stream; f):
  reduce stream as $s (null;
      [., ($s | f)] | transpose | map(add));

sigmas(inputs | .game; [.player1.score, .player2.score])
| {player1: .[0], player2: .[1]}

注意,此处定义的sigmas可以任意处理许多求幂。对于读者来说,这是一个更简单的练习,它避免了将求知数指定为列表的需要,这是更简单的练习:-)

jq.jq

通常,通用函数可以包含在“标准jq库”中。例如,如果您的实用程序函数位于〜/ .jq / jq.jq中,则假定pwd没有不同的jq.jq,则可以编写(针对第一个问题的解决方案):

jq -n 'include "jq"; sigma(inputs.game.player1.score)' foo.json

图书馆的严格收录

为了避免与模块路径相关的困难,有时在includeimport指令中指定路径是有意义的,例如:

jq -n 'include "jq" {search: "~/jq"}; ...'

1
投票

一个选项是使用reduce,例如:

jq -n 'reduce inputs.game.player1.score as $score (0; . + $score)' file

另一个是:

jq -n '[inputs.game.player1.score] | add' file

但是这在输入较大时效果不如第一个。


这也是一个涵盖第二个Q的更通用的一个>>

jq -n 'reduce inputs.game as $game ({};
  reduce ($game|keys_unsorted)[] as $player (.;
    .[$player] += $game[$player].score
  )
)' file

0
投票

这是从对象流定义表(即电子表格)的角度提出的通用解决方案。该解决方案也是有效的(无拖延)和稳健的(无关于键的顺序或存在的假设)。


0
投票

这是一个具有帮助功能的解决方案,它使用

© www.soinside.com 2019 - 2024. All rights reserved.