jsonjq

JQ — Return first element that satisfies a predicate


I have a string like:

"The sky is blue."

and a JSON file like

[
  {
    "id": 1234,
    "name": "Entry 1",
    "keywords": [
      "orange",
      "yellow"
    ]
  }, 
  {
    "id": 2345,
    "name": "Entry 2",
    "keywords": [
      "red",
      "blue",
      "pink"
    ]
  }, 
  {
    "id": 3456,
    "name": "Entry 3",
    "keywords": [
        "green",
        "blue",
        "black"
    ]
  }
]

I want to return the first element which has a keyword that can be found in the string.

In this case I would like to have the element with the id 2345, because the keyword "blue" occurs in the string, and it is the first match.

Is there a one-line solution with JQ (e.g. with various pipes)? I'm not looking for a solution with loops.


Solution

  • A variation based on Inian's excellent answer:

    first(.[] | select(.keywords | any(inside("the sky is blue."))))
    

    If we have the data in input.json and the string "the sky is blue." passed as a parameter we have:

    jq --arg str 'the sky is blue' 'first(.[] | select(.keywords | any(inside($str))))' input.json
    

    This returns the first element which keywords is contained within $str:

    {
      "id": 2345,
      "name": "Entry 2",
      "keywords": [
        "red",
        "blue",
        "pink"
      ]
    }