用jq
的语言,为什么
$ jq --compact-output reduce (1,2,3,4) as $i ([]; . + [$i])
[1,2,3,4]
与
不同$ jq --compact-output (1,2,3,4) | reduce . as $i ([]; . + [$i])
[1]
[2]
[3]
[4]
我有一个理论上的问题,我想出了一种方法来获得想要的转换,但是我仍然不完全理解为什么我的第一次尝试失败了,我想解释一下。
jqPlay上的互动示例
我有输入
{
"data": {
"k1": "v1"
},
"item": {
"data": {
"k2": "v2"
}
},
"list": {
"item": {
"data": {
"k3": "v3",
"k4": "v4"
}
}
}
}
,我想将作为“数据”键的直接子级的所有键的所有值收集到一个数组中。所以我想要的输出是
["v1","v2","v3","v4"]
我最终发现这可行
jq --compact-output '[.. | .data? | select(.) | to_entries | .[].value]'
我的问题是,为什么我不能使它与reduce
一起使用?我最初尝试过
.. | .data? | select(.) | to_entries | .[].value | reduce . as $v ([]; . + [$v])
但这给了我
["v1"]
["v2"]
["v3"]
["v4"]
相反。我的问题是为什么? reduce
应该迭代多个值,但是它会迭代哪种类型的多个值,以及哪种类型的值被视为单独的reduce
语句的单独输入?
我想我的基本困惑是.
(点)何时是具有4个结果的表达式,什么时候是4个表达式?或者,如果.
始终是一个带有1个结果的表达式,那么如何将4个结果收集回1,这就是reduce
的全部含义?数组运算符是唯一的方法吗?
答案 0 :(得分:2)
以下形式的表达式:
reduce STREAM as ...
减少给定的流,而复合表达式:
STREAM | reduce . as ...
为流中的每个项目调用一次reduce
,对于每次调用,.
就是那个项目。
如果在这种情况下不清楚流的概念,那么您可能有兴趣阅读我写的面向流的jq简介: https://github.com/pkoppstein/jq/wiki/A-Stream-oriented-Introduction-to-jq