【问题标题】:jq: index/1 not working when element is an arrayjq:当元素是数组时,index/1 不起作用
【发布时间】:2018-07-31 15:00:21
【问题描述】:
echo "[[{\"t\":4}]]" | jq 'index(.[0])'

我期待它返回 0。 相反,它返回 null。 索引仅适用于带有标量的数组,但是一旦存在嵌套数组,它就会返回 null。 为什么?

【问题讨论】:

    标签: arrays json indexing jq


    【解决方案1】:

    因为显然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。

    因此,在您的情况下,它试图在包含列表(而不是直接对象)的列表中查找由对象组成的单个元素子序列。

    【讨论】:

      【解决方案2】:

      在 jq 手册中,在标题 indices 下有一个关于 index 语义的提示。简而言之,看似错误的行为实际上是一个“特征”。也就是说,以下说明了预期的行为:

      $ jq 'index([1,2])'
      [1,2]
      0
      $ jq 'index([[1,2]])'
      [[1,2]]
      0
      $ 
      

      所以要搜索 JSON 实体 X,使用 index([X]) 总是安全的。不幸的是,由于index 当前的实现方式,它没有(应该)那么高效,但这是一个不同的话题。

      不过,.[[X]]IN/1 值得了解。

      .[[X]]

      一个鲜为人知的事实是后缀方括号提供“索引”功能:

      $ 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
      

      输入/1

      jq 的“主”版本有一对简单的面向流的过滤器(命名为IN),用于检查项目是否在流中。这是IN/1 的有效定义,如果您的jq 有first/1,则可以使用它:

      def IN(s): . as $in | first( if (s == $in) then true else empty end ) // false;
      

      这里s 是要搜索的流。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-15
        • 1970-01-01
        • 2013-04-08
        • 2017-07-16
        相关资源
        最近更新 更多