I have a list of movies like this:
[
{
"title":"X",
"genres":[
{
"tag":"Horror"
},
{
"tag":"Thriller"
},
{
"tag":"Mystery"
}
]
},
{
"title":"Zero Dark Thirty",
"genres":[
{
"tag":"Thriller"
},
{
"tag":"Drama"
},
{
"tag":"History"
},
{
"tag":"War"
}
]
}
]
I want to query all unique genres and count the number of movies, where the output looks like this:
{
"Horror":1,
"Thriller":2,
"Mystery":1,
"Drama":1,
"History":1,
"War":1
}
Is this possible with jq?
>Solution :
Yes, it is.
- Extract all genres into array
- Group genres
- Map to a key-value pair (key = any element of the group, we’ll take the first; value = count of elements in the group)
- Build object from key-value pairs
map(.genres[].tag)
| group_by(.)
| map({ key:first, value:length })
| from_entries
Output:
{
"Drama": 1,
"History": 1,
"Horror": 1,
"Mystery": 1,
"Thriller": 2,
"War": 1
}
Alternatively, use a reduce based approach and simply increase a counter:
reduce .[].genres[].tag as $genre ({}; .[$genre] += 1)
This is likely more efficient than building an array and grouping.