So I have an interesting problem with filtering collections, I have a data class as follows:
data class Route(
val id: Int,
val name: String,
val weeklyPrice: Double?,
val monthlyPrice: Double?,
val seasonalPrice: Double?,
)
I'm displaying an ArrayList in the UI and the user has the ability to filter the list based on whether the route has "weekly/monthly/seasonal" prices, bear in mind I'm using checkboxes not radio buttons so the user can filter using multiple options. ie. only weekly, or both weekly and monthly and so on.
My issue is that using the filter function and a predicate I can only filter based on one attribute at a time like so:
routes.filter {
it.weeklyPrice != null
}
But sometimes I'd actually filter out values I wanted to keep based on another condition, for example a user doesn't want routes with weekly prices, so I filter those out but he wants ones with monthly ones but some of them were already filtered out based on the fact that they had weekly prices as well.
Any help would be appreciated, I'm sure it can be done I just haven't figured out how, maybe the problem is in how the data is represented in the first place? I'm not sure.
Much thanks in advance.
One approach would be to generate a list of filters, e.g. List<(Route) -> Boolean>
, and then just invalidate your view whenever the list of filters change.
So for example you have something like:
// Use your own logic based on user selection here
private fun generateFilters() = listOf<(Route) -> Boolean>(
{ it.id != 0 },
{ it.weeklyPrice != null }
)
Then, your view is generated based on this set of filter, i.e.:
private fun filterRoutes(routes: List<Route>, filters: List<(Route) -> Boolean>) =
routes.filter { route -> filters.all { filter -> filter(route) }
You could even add an extension function on List<T>
to provide a filterAll
functionality, something like:
private fun <T> List<T>.filterAll(filters: List<(T) -> Boolean>) =
filter { item -> filters.all { filter -> filter(item) } }
Then your view logic just becomes:
routers.filterAll(generateFilters())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With