【问题标题】:select array by any element exactly matched to specified value通过与指定值完全匹配的任何元素选择数组
【发布时间】:2019-01-17 21:50:24
【问题描述】:

有人知道如何实现吗?

我有一个数组,它有一个嵌套数组,比如 tagNames,我想选择 tagNames 包含“auto-test”的所有项目,而不是“auto-test2”。

{
  "servers":[
      {"id":1, "tagNames": ["auto-test",  "xxx"]},
      {"id":2, "tagNames": ["auto-test2", "xxxx"]}
  ]
}

到目前为止,我正在使用

echo '{"servers":[{"id":1,"tagNames":["auto-test","xxx"]},{"id":2,"tagNames":["auto-test2","xxxx"]}]}' |\
jq  '[ .servers[] | select(.tagNames | contains(["auto-test"])) ]'

我有两条记录,但我只想要第一条。

[
  {
    "id": 1,
    "tagNames": [
      "auto-test",
      "xxx"
    ]
  },
  {
    "id": 2,
    "tagNames": [
      "auto-test2",
      "xxxx"
    ]
  }
]

所以我想要这个:

[
  {
    "id": 1,
    "tagNames": [
      "auto-test",
      "xxx"
    ]
  }
]

有什么想法吗?

【问题讨论】:

    标签: json jq


    【解决方案1】:

    另一种解决方法是使用成语:first(select(_)):

    jq '.servers[] | first(select(.tagNames[]=="auto-test"))' file
    

    如果first 被省略,那么servers 数组中的同一项目可能会被多次发出。

    【讨论】:

      【解决方案2】:

      一种方法是使用index/1,例如

      .servers[]
      | select( .tagNames | index("auto-test"))
      

      这会产生:

      {"id":1,"tagNames":["auto-test","xxx"]}
      

      如果您希望将其包裹在一个数组中,您可以(例如)将上面的过滤器包裹在方括号中。

      【讨论】:

      • 感谢您的精彩回答!我不明白为什么会这样。 index 返回第一个出现的位置,所以它可能是一个从 0 开始的数字,而 0 应该转换为 false,它应该不起作用,但为什么现在它起作用了?
      • 我还发现index操作符有一个优势,它甚至可以处理空数组(tagNames = null)。
      • index/1 要么返回偏移量(即从 0 开始的索引),要么返回 null 如果项目(或序列)不存在。
      • 感谢您的回答。知道了。虽然这是最简单的答案,但抱歉,由于它有点晦涩难懂,我最终将接受的答案交给了 Jeff Mercado, jq '[ .servers[] | select(any(.tagNames[]; . == "auto-test")) ]'
      【解决方案3】:

      您不应该使用contains/1,因为它不会按您预期的方式工作,尤其是在您处理字符串时。它将递归检查是否包含所有部分。所以它不仅会检查字符串是否包含在数组中,还会检查字符串是否也是子字符串。

      你需要写出你的条件,检查所有标签是否符合你的条件。

      [.servers[] | select(any(.tagNames[]; . == "auto-test") and all(.tagNames[]; . != "auto-test2"))]
      

      【讨论】:

      • 非常感谢。这是最容易理解的方法。我最终得到jq '[ .servers[] | select(any(.tagNames[]; . == "auto-test")) ]'
      猜你喜欢
      • 2013-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 2020-03-06
      相关资源
      最近更新 更多