Michael
Michael

Reputation: 187

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?

Upvotes: 8

Views: 26741

Answers (2)

voddan
voddan

Reputation: 33769

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]!! }) }

Upvotes: 17

Cortwave
Cortwave

Reputation: 4907

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]!! }
                }

Upvotes: 3

Related Questions