echo "[[{\"t\":4}]]" | jq 'index(.[0])'
我原以为这会返回0。 相反,它返回null。 索引仅适用于带有标量的数组,但一旦有嵌套数组,它就会返回null。 为什么呢?
答案 0 :(得分:2)
因为显然index
需要查找元素的子序列,标量是一个等同于一个元素序列的特殊情况。
比较三种情况:
echo "[0,2,0,3,0,6,0,2]" | jq 'index(2)'
echo "[0,2,0,3,0,6,0,2]" | jq 'index([2])'
echo "[0,2,0,3,0,6,0,2]" | jq 'index([2,0])'
他们都返回1.
所以在你的情况下,它试图找到一个单元素子序列,该子序列由列表中包含列表的对象组成(而不是直接包含对象)。
答案 1 :(得分:1)
在jq手册中,有一个关于标题index
下indices
的语义的提示。简而言之,看似错误的行为实际上是一个“特征”。也就是说,以下说明了预期的行为:
$ jq 'index([1,2])'
[1,2]
0
$ jq 'index([[1,2]])'
[[1,2]]
0
$
因此,要搜索JSON实体X,使用index([X])
始终是安全的。不幸的是,由于index
目前的实施方式,它并不像它应该的那样有效,但这是一个不同的主题。
但是值得了解.[[X]]
和IN/1
。
一个鲜为人知的事实是后缀方括号提供了“索引”功能:
$ jq -nc '[1,2,30,3,3][[3]]'
[3,4]
$ jq -nc '[[1],2,30,3][[1]]'
[]
$ jq -nc '[[1],2,30,3][[[1]]]'
[0]
$ jq -nc '[{a:1},2,30,3][[ {a:1} ]]'
[0]
所以要恢复输入数组中X的最小索引:
.[[X]][0]
与index/1
一样,如果X不在输入数组中,则返回null:
$ jq -n '[1,2,3][ [4] ][0]'
null
jq的“主”版本有一对简单的面向流的过滤器(名为IN
),用于检查项目是否在流中。这是IN/1
的有效def,如果您的jq有first/1
,则可以使用
def IN(s): . as $in | first( if (s == $in) then true else empty end ) // false;
此处s
是要搜索的流。