Reputation: 13
I have a slightly modified JSON file with iOS firmware information from https://api.ipsw.me/v2.1/firmwares.json. This is a simplified version:
Input
{
"AppleTV5,3": {
"firmwares": [
{
"version": "9.2",
"buildid": "13Y234"
},
{
"version": "9.1.1",
"buildid": "13U717"
},
{
"version": "9.1",
"buildid": "13U85"
}
],
"bdid": 52,
"name": "Apple TV 4 (2015)"
},
"AppleTV3,2": {
"firmwares": [
{
"version": "8.4.1",
"buildid": "12H523"
},
{
"version": "8.3",
"buildid": "12F69"
}
],
"bdid": 0,
"name": "Apple TV 3 (2013)"
},
"AppleTV3,1": {
"firmwares": [
{
"version": "8.4.1",
"buildid": "12H523"
},
{
"version": "8.3",
"buildid": "12F69"
},
{
"version": "8.2",
"buildid": "12D508"
}
],
"bdid": 0,
"name": "Apple TV 3"
}
}
I want to write a jq query that returns each outer object with only the latest firmware object in the firmwares
array. E.g.:
Desired output
{
"AppleTV5,3": {
"firmwares": [
{
"version": "9.2",
"buildid": "13Y234"
}
],
"bdid": 52,
"name": "Apple TV 4 (2015)"
},
"AppleTV3,2": {
"firmwares": [
{
"version": "8.4.1",
"buildid": "12H523"
}
],
"bdid": 0,
"name": "Apple TV 3 (2013)"
},
"AppleTV3,1": {
"firmwares": [
{
"version": "8.4.1",
"buildid": "12H523"
}
],
"bdid": 0,
"name": "Apple TV 3"
}
}
I can get a list of the latest firmwares
objects with:
.[].firmwares | max_by(.version)
I can get just the values from version
with:
.[].firmwares | map(.version | values) | max
And I can get the outer AppleTV objects with firmwares
matching a particular version
:
[ . | to_entries[] | .value.firmwares |= map ( select ( .version == "8.3" ) ) ] | from_entries
But I can't seem to combine the techniques to get my desired output. Can anyone help out?
Upvotes: 1
Views: 231
Reputation: 14663
Here is a solution which uses reduce to visit each key of the object and update corresponding .firmwares
to the latest version
reduce keys[] as $i (
.
; .[$i].firmwares |= [max_by(.version)]
)
Upvotes: 1
Reputation: 134881
You should think of it as updating the firmwares
arrays. We're updating it with a filtered version where it the max version is selected.
.[].firmwares |= [ max_by(.version | split(".") | map(tonumber)) // empty ]
Upvotes: 1