Reputation: 1
I'm learning Groovy and I want to filter JSON (list of maps):
[
{
"username":"unnamed",
"status":"offline",
"last_activity":"2021-01-01",
},
{
"username":"pachimasu",
"status":"active",
"last_activity":"2021-03-11",
},
{
"username":"user",
"status":"active",
"last_activity":"2021-03-11",
}
]
I want to filter active
accounts. Expected output:
[
{
"username":"pachimasu",
"status":"active",
"last_activity":"2021-03-11",
},
{
"username":"user",
"status":"active",
"last_activity":"2021-03-11",
}
]
I ran:
def j = new JsonSlurper().parseText(text)
def expected = j.findAll {
it.value.status == 'active'
}
But it throws exception: java.lang.NullPointerException: Cannot get property 'status' on null object
. As far I understand, findAll
looping through elements inside lists, but not maps content inside this list. So, how can i loop through maps inside list and filter list by map values?
UPDATE
Source:
[
{
"username":"unnamed",
"status":"offline",
"last_activity":"2021-01-01",
"subscribers": 100,
"subscriptions": 3
},
{
"username":"pachimasu",
"status":"active",
"last_activity":"2021-03-11",
"subscribers": 1,
"subscriptions": 28
},
{
"username":"user",
"status":"active",
"last_activity":"2021-03-11"
}
]
I want to get keys that have Integer values:
[
{
"subscribers": 100,
"subscriptions": 3
},
{
"subscribers": 1,
"subscriptions": 28
}
]
Upvotes: 0
Views: 490
Reputation: 37008
You can combine findResults
and subMap
like so:
def data = [["username":"unnamed",
"status":"offline",
"last_activity":"2021-01-01",
"subscribers": 100,
"subscriptions": 3],
["username":"pachimasu",
"status":"active",
"last_activity":"2021-03-11",
"subscribers": 1,
"subscriptions": 28],
["username":"user",
"status":"active",
"last_activity":"2021-03-11"]]
println data.findResults{
it.containsKey('subscriptions') ? it.subMap('subscriptions','subscribers') : null
}
// → [[subscriptions:3, subscribers:100], [subscriptions:28, subscribers:1]]
Note, that you need some condition to mark an item as valid. Here the
existence of a subscriptions
key is used.
Upvotes: 1
Reputation: 20699
Down below is a simple example of filtering by a known key-value, as well as by value only:
def j = new groovy.json.JsonSlurper().parseText '''
[
{
"username":"unnamed",
"status":"offline",
"last_activity":"2021-01-01",
},
{
"username":"pachimasu",
"status":"active",
"last_activity":"2021-03-11",
},
{
"username":"user",
"status":"active",
"last_activity":"2021-03-11",
}
]'''
def expectedByKey = j.findAll{ it.status == 'active' }
assert expectedByKey.size() == 2
def expectedByValue = j.findAll{ it.any{ _, value -> value == 'offline' } }
assert expectedByValue.size() == 1
UPDATE:
By Integers can be filtered like so:
import groovy.json.*
def j = new JsonSlurper().parseText '''
[
{
"username":"unnamed",
"status":"offline",
"last_activity":"2021-01-01",
"subscribers": 100,
"subscriptions": 3
},
{
"username":"pachimasu",
"status":"active",
"last_activity":"2021-03-11",
"subscribers": 1,
"subscriptions": 28
},
{
"username":"user",
"status":"active",
"last_activity":"2021-03-11"
}
]'''
def expectedByInts = j.findResults{ it.findAll{ _, v -> v in Integer } ?: null }
JsonOutput.prettyPrint JsonOutput.toJson( expectedByInts )
prints
[
{
"subscribers": 100,
"subscriptions": 3
},
{
"subscribers": 1,
"subscriptions": 28
}
]
Upvotes: 2