在 jq 中使用解构替代运算符 ?//

Using the Destructuring Alternative Operator ?// in jq

在最新的 jq 1.6 版本中有一个功能 Destructuring Alternative Operator: ?// 我正试图用它来解析我的 笨拙地转换 XML.

这是我在 jq play:

上玩过的简化示例
{"data":[
    {"fruit":"orange","details":  {"colour":"orange"}},
    {"fruit":"apple", "details": [{"colour":"red"},{"colour":"green"}]}
]}

关键点有时 details 是一个对象,有时它是一个对象数组,引用文档 “我们可以使用解构替代运算符来处理这种结构变化只是

如果我更改输入数据,那么 details 始终是一个数组,我可以轻松创建 the output I want

.data[] | "\(.fruit) - \(.details[].colour)"


{"data":[
    {"fruit":"orange","details": [{"colour":"orange"}]},
    {"fruit":"apple", "details": [{"colour":"red"},{"colour":"green"}]}
]}


"orange - orange"
"apple - red"
"apple - green"

然而,使用带有 ?// 的原始数据最好的 I can come up with 是:

.data[] as {$fruit, details: $colour} ?// {$fruit, details: $colour} | "\($fruit) - \($colour)"

"orange - {\"colour\":\"orange\"}"
"apple - [{\"colour\":\"red\"},{\"colour\":\"green\"}]"

and this (which is pretty much a copy of one of the examples):

.data[] as {$fruit, details: {$colour}} ?// {$fruit, details: [{$colour}]} | "\($fruit) - \($colour)"

"orange - orange"
"apple - red"

solutions using if else 但我特别感兴趣的是这个功能是如何工作的,以及我需要做什么才能得到它来创建我想要的输出。

生成您期望的输出的一种方法是使用 ? // 而不是 ?//:

.data[]
| (.details | (.colour? // (.[] | .colour))) as $colour
| "\(.fruit) - \($colour)"

至于 ?//,您可能找错了树:destructuring-alternative 运算符不是 stream-oriented。也就是说,当 non-empty 数组与 [$foo] 匹配时,$foo 只会匹配数组中的第一项,而不匹配序列中的项。

但是,如果您真的想使用 ?//,对于您的特定情况,您可以这样写:

.data[]
| .details as [$colour1, $colour2] ?// $colour1
| "\(.fruit) - \($colour1|.colour)",
  "\(.fruit) - \($colour2//empty|.colour)"