Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin - List within a List filtering

I have those data classes:

data class RouteType(

            @SerializedName("type")
            val type: String,

            @SerializedName("items")
            val items: List<RouteItem>)


data class RouteItem(

            @SerializedName("id")
            val id: String,

            @SerializedName("route")
            private val route: List<DoubleArray>)

I want to filter list of RouteType by type and filter list of RouteItem in it by id.

My code now:

// val filter: HashMap<String, List<String>>

val result = routeTypes  // List<RouteType>
                .filter { it.type in filter.keys }
                .map {
                    routeType -> routeType.items.filter { it.id in filter[routeType.type]!! }
                }

How to make .map return list with filtered list in it? Or maybe there's another way?

EDIT

Thanks, but flatmap not exactly what I need, I think. flatmap returns nested list(List<RouteItem>), but I want List<RouteType>.

I got it by this code:

val result = routeTypes
                .filter { it.type in filter.keys }
                .map {
                    routeType -> RouteType(
                        routeType.type,
                        routeType.items.filter { it.id in filter[routeType.type]!! })
                }

Is there another way to get it?

like image 336
Michael Avatar asked Apr 13 '16 20:04

Michael


People also ask

How do you filter an array of objects in Kotlin?

If you want to use element positions in the filter, use filterIndexed() . It takes a predicate with two arguments: the index and the value of an element. To filter collections by negative conditions, use filterNot() . It returns a list of elements for which the predicate yields false .

How do I filter data with Kotlin?

If we want to filter using element index or position, we have to use filterIndexed(). filterIndexed() function takes a predicate with two arguments: index and the value of an element. We can filter the collections by negative conditions by using filterNot().


2 Answers

Since your data is immutable (that's a good thing) you need to copy it while filtering. Use copy to make it more extensible:

val result = routeTypes
        .filter { it.type in filter.keys }
        .map { it.copy(items = it.items.filter { it.id in filter[routeType.type]!! }) }
like image 129
voddan Avatar answered Oct 05 '22 15:10

voddan


You can use flatMap for this, it works as map, but merges all your mapped collections to one:

val result = routeTypes  // List<RouteType>
                .filter { it.type in filter.keys }
                .flatMap {
                    routeType -> routeType.items.filter { it.id in filter[routeType.type]!! }
                }
like image 34
Cortwave Avatar answered Oct 05 '22 15:10

Cortwave