jnber5
jnber5

Reputation: 13

jq filter items where values in a nested array array are different

Let's say I have the following json. I want to get all the items where the "employee" had different teams over the year.

[
    {
        "id": 122343,
        "name": "Tom Muller",
        "teams": [
            {
                "year": "2010-2011",
                "team_id": 27
            },
            {
                "year": "2011-2012",
                "team_id": 27
            },
            {
                "year": "2013-2014",
                "team_id": 27
            }
        ]
    },
    {
        "id": 338744,
        "name": "Eric Gonzales",
        "teams": [
            {
                "year": "2010-2011",
                "team_id": 12
            },
            {
                "year": "2011-2012",
                "team_id": 17
            },
            {
                "year": "2013-2014",
                "team_id": 17
            }
        ]
    }
]

I would like to query the array with jq and the output would return

{
        "id": 338744,
        "name": "Eric Gonzales",
        "teams": [
            {
                "year": "2010-2011",
                "team_id": 12
            },
            {
                "year": "2011-2012",
                "team_id": 17
            },
            {
                "year": "2013-2014",
                "team_id": 17
            }
        ]
    }

How would I write such a query ?

Thanks

Upvotes: 1

Views: 356

Answers (1)

pmf
pmf

Reputation: 36151

With unique_by you can reduce the .teams array to those that differ in their .team_id, and with select and length you can filter for those that have strictly more than just one such item.

jq '.[] | select(.teams | unique_by(.team_id) | length > 1)'
{
  "id": 338744,
  "name": "Eric Gonzales",
  "teams": [
    {
      "year": "2010-2011",
      "team_id": 12
    },
    {
      "year": "2011-2012",
      "team_id": 17
    },
    {
      "year": "2013-2014",
      "team_id": 17
    }
  ]
}

Demo

This gives you a stream of objects (in case there's more than one result). Use map(select(…)) instead of .[] | select(…) if you want to have them as an array.

Upvotes: 1

Related Questions