pachimasu
pachimasu

Reputation: 1

Filter maps inside list

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

Answers (2)

cfrick
cfrick

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

injecteer
injecteer

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

Related Questions