jq使用parent获取数组中的每个值

时间:2017-08-31 13:41:12

标签: json jq

我有json,如下所示。我希望得到一个输出,每个计时器记录包含一行,但包含服务名称。

{  
   "services":{  
      "service":[  
         {  
            "name":"Test Value",
            "timer":[  
               { "datetime":"08/30/2017 16:33:35", "value":"625" },
               { "datetime":"08/30/2017 16:22:38", "value":"240" }
            ]
         },
         {
            "name":"Test Value 2",
            "timer":[
               { "datetime":"08/30/2017 16:07:38", "value":"432" },
               { "datetime":"08/30/2017 15:59:07", "value":"1355" }
            ]
         }
      ]
   }
}

我提出了.services.service[].name as $name | .services.service[].timer | map([ $name, .datetime, .value ]),它让我

[["Test Value","08/30/2017 16:33:35","625"],["Test Value","08/30/2017 16:22:38","240"]]
[["Test Value","08/30/2017 16:07:38","432"],["Test Value","08/30/2017 15:59:07","1355"]]
[["Test Value 2","08/30/2017 16:33:35","625"],["Test Value 2","08/30/2017 16:22:38","240"]]
[["Test Value 2","08/30/2017 16:07:38","432"],["Test Value 2","08/30/2017 15:59:07","1355"]]

我期待的输出是

[["Test Value","08/30/2017 16:33:35","625"],["Test Value","08/30/2017 16:22:38","240"]]
[["Test Value 2","08/30/2017 16:07:38","432"],["Test Value 2","08/30/2017 15:59:07","1355"]]

但请注意,服务和计时器组的值都是重复的。我错过了什么?

3 个答案:

答案 0 :(得分:3)

.services.service[]|[{name,timer:.timer[]}|[.name,.timer[]]]会为您提供预期的输出

.services.service[]|{name,timer:.timer[]}|[.name,.timer[]](没有数组聚合)会为每个计时器提供一个结果:

["Test Value","08/30/2017 16:33:35","625"]
["Test Value","08/30/2017 16:22:38","240"]
["Test Value 2","08/30/2017 16:07:38","432"]
["Test Value 2","08/30/2017 15:59:07","1355"]

您在尝试中遗漏的是

  

表达式exp为$ x | ...表示:对于表达式exp的每个值,使用整个原始输入运行管道的其余部分,并将$ x设置为该值。因此,作为foreach循环的功能。

如果你真的想使用变量,你需要这样做:.services.service[]| .name as $name | .timer | map([ $name, .datetime, .value ])

答案 1 :(得分:1)

这是另一个演示阵列构造函数变体的解决方案。请注意每个[]的位置略有不同。使用您的数据,此过滤器

requires
  rtl,
  vcl,
  vclx,
  // etc...
  TeePro923,
  TeeUI923,
  Tee923,
  TeeImage923,
  TeeGL923,
  // etc...

生成单个对象流

 .services.service[] | {name} + .timer[]

此过滤器

{"name":"Test Value","datetime":"08/30/2017 16:33:35","value":"625"}
{"name":"Test Value","datetime":"08/30/2017 16:22:38","value":"240"}
{"name":"Test Value 2","datetime":"08/30/2017 16:07:38","value":"432"}
{"name":"Test Value 2","datetime":"08/30/2017 15:59:07","value":"1355"}

为每个服务生成对象数组

 .services.service[] | [ {name} + .timer[] ]

此过滤器

[{"name":"Test Value","datetime":"08/30/2017 16:33:35","value":"625"},{"name":"Test Value","datetime":"08/30/2017 16:22:38","value":"240"}]
[{"name":"Test Value 2","datetime":"08/30/2017 16:07:38","value":"432"},{"name":"Test Value 2","datetime":"08/30/2017 15:59:07","value":"1355"}]

生成数组流

 .services.service[] | {name} + .timer[] | [.[]]

和此过滤器

["Test Value","08/30/2017 16:33:35","625"]
["Test Value","08/30/2017 16:22:38","240"]
["Test Value 2","08/30/2017 16:07:38","432"]
["Test Value 2","08/30/2017 15:59:07","1355"]

为每个服务生成数组数组

 .services.service[] | [ {name} + .timer[] | [.[]] ]

答案 2 :(得分:0)

我认为尝试根据您的数据所处的级别以及您希望它在结果中的位置进行可视化会很有帮助。展平数据层次结构时,我发现如果将其作为一个级别的值,并将其与下一级别的值相结合,则会更容易思考。

因此,查看各个服务对象,您需要获取名称,并将其与其计时器对象的属性组合,并为每个组合生成结果。所以从那里开始:

[.name] + (properties of the timer objects)

然后您需要生成properties of the timer objects

.timer[] | [.datetime, .value]

您可以将其理解为:“对于timer数组中的每个项目,创建一个由datetimevalue属性组成的数组。”

一旦你把所有东西都放在同一水平,你可以根据需要重新安排值,但幸运的是,在我们的情况下,一切都在我们想要的地方。

放在一起,此表达式生成名称,日期时间和值的各个数组,但您希望在数组中收集它们。所以把它们放进去。

[[.name] + (.timer[] | [.datetime, .value])]

当你把它们放在一起时,你会得到你的结果。

.services.service[] | [[.name] + (.timer[] | [.datetime, .value])]