Hello everyone, I have been into kotlin for few mo...
# android
p
Hello everyone, I have been into kotlin for few months, one issue I started facing in the early days of my learning. I will be very much thankful for any response regarding the same. I have a JSON list, in which I need to filter the data based on some filters. I was using predicate for filtering, but as per my need I need to filter the nested list, and if here I use predicates I am left with 3 test predicates that's
Any, None, and All
but as I want only matched data and which I am not getting using any of these predicates. As Any returns true if at least there is one match element, and All returns true if there are all matched elements but how can I get only the matched elements from the nested list irrespective of any non-matched element. I can use the traditional approach of looping through the list, but I wanted to know whether it is possible using a predicate. Here's the sample JSON I am trying to get the center whose session elements contains
min_age_limit is > 18
and
available_dose_1 > 0
.
Copy code
{
"centers": [
	{
		....
		"sessions": [
			{
				"session_id":"adad",
				...
				"min_age_limit":45,
				"available_capacity_dose1": 5,
				"available_capacity_dose2": 5
				...
			},
			{
				"session_id":"adad1",
				...
				"min_age_limit":18,
				"available_capacity_dose1": 0,
				"available_capacity_dose2": 5
				...
			},
			{
				"session_id":"adad2",
				...
				"min_age_limit":18,
				"available_capacity_dose1": 5,
				"available_capacity_dose2": 0
				...
			}
		]
	}
	....
	]
}
b
I think the first step is to serialize the JSON into simple Kotlin `data class`es, then rephrase the problem in terms of filtering a
List<Session>
and it should become much simpler.
p
Thank you for your response, yes I have created a
data class
for this JSON. here it goes
Copy code
data class Center(
        @SerializedName("name")
        val name: String?,
        @SerializedName("address")
        val address: String?,
        @SerializedName("pincode")
        val pincode: Int?,
        @SerializedName("fee_type")
        val feeType: String?,
        @SerializedName("sessions")
        var sessions: List<Session>?
)
But I not getting how can I add a filter to the session list, I need to loop through every center. But I am couldn't able to do.
b
Maybe something like this?
Copy code
fun isValidSession(session: Session) = session.minAgeLimit > 18 && session.availableDose > 0
val centersWithAtLeastOneValidSession = centers.filter { center ->
    center.sessions.any { session -> isValidSession(session) }
}
p
Thank you again, but I want only the valid sessions.
Any
will give the session list if at least one of the sessions satisfies the condition so it ends up with some invalid session too which doesn't satisfy the conditions. But I want only the matched sessions.
b
Ok, in this case, this is just a list of all valid sessions.
Copy code
val allValidSessions = centers.map { center ->
    center.sessions.filter { session -> isValidSession(session)}
}.flatten()
Don't need to use a predicate.
It also might make sense to move some of this logic into
Center
itself to make things more intuitive. (i.e.):
Copy code
data class Center(
    /* other properties .... */
    val sessions: List<Session>
) {
    fun hasValidSession() = sessions.any(::isValidSession)
    fun getValidSessions() = sessions.filter(::isValidSession)
}
p
Thank you @bsimmons it worked. Some customization was needed I did.
Copy code
val allValidSessions = it?.data?.centers?.sortedBy { it.name }?.map { center ->
    center to center.sessions?.filter { session -> isValidSession(session, prefAge[0], selectedDose) }
}?.toMap()
👍 1