Home > Back-end >  Searching a list of objects with identical keys for specific key, value pairs with JQ
Searching a list of objects with identical keys for specific key, value pairs with JQ

Time:06-15

For a JSON object like the one below,

{
    "company1": {
        "employees": [
            {
                "name": "John",
                "title": "CEO"
            },
            {
                "name": "Jason",
                "title": "CFO"
            },
            {
                "name": "Jackson",
                "title": "Sales Representative"
            }
        ]
    },
    "company2": {
        "employees": [
            {
                "name": "Amy",
                "title": "CEO"
            },
            {
                "name": "James",
                "title": "Software Engineer"
            },
            {
                "name": "John",
                "title": "Sales Representative"
            }
        ]
    }
}

let's say I want to find all the companies where the CEO is named John. I have tried using this filter:

map_values(select(.employees | select((.[] .name | contains("John")) and (.[] .title | contains("CEO")) )))

which essentially searches the entire list for a "name" field containing "John" and a "title" field containing "CEO". The problem is, as long as somewhere in the employees list there is a "name" field containing "John" and a "title" field containing "CEO", it will return the company as a valid result. This means that this filter will return both companies if applied to the JSON object above, as in company2, there is indeed an employee named John (but he is not a CEO), and there is a CEO (but she is not John).

How can have it work correctly (without changing the structure of the data) and only return company1?

CodePudding user response:

Use and to match both criteria, and use any within select to make pass a company if at least one of its employees fulfills the condition:

map_values(select(any(.employees[]; .name == "John" and .title == "CEO")))
{
  "company1": {
    "employees": [
      {
        "name": "John",
        "title": "CEO"
      },
      {
        "name": "Jason",
        "title": "CFO"
      },
      {
        "name": "Jackson",
        "title": "Sales Representative"
      }
    ]
  }
}

Demo

  • Related