代码之家  ›  专栏  ›  技术社区  ›  osexp2000

按与指定值完全匹配的任何元素选择数组

  •  0
  • osexp2000  · 技术社区  · 6 年前

    我有一个嵌套数组的数组,比如说标记名,我想选择所有标记名包含“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"
        ]
      }
    ]
    

    知道吗?

    3 回复  |  直到 6 年前
        1
  •  2
  •   Jeff Mercado    6 年前

    你不应该用 contains/1 因为它不会像你期望的那样工作,特别是当你处理字符串的时候。它将递归地检查是否包含所有部分。因此,它不仅会检查字符串是否包含在数组中,而且还会检查字符串是否也是子字符串。

    您需要写出您的条件,根据您的条件检查任何和所有标记。

    [.servers[] | select(any(.tagNames[]; . == "auto-test") and all(.tagNames[]; . != "auto-test2"))]
    
        2
  •  1
  •   peak    6 年前

    一种方法是 index/1

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

    这会产生:

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

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

        3
  •  0
  •   peak    6 年前

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

    如果 first servers 数组可能被多次发出。