How do I transform nested collections using flatMap in Kotlin?

In Kotlin, flatMap is used to transform each element into a collection and then flatten the results into a single list.

Basic idea

val result = items.flatMap { item ->
    // return a collection for each item
}

It is similar to:

items.map { ... }.flatten()

but more concise.


Example: flatten nested lists

val nested = listOf(
    listOf(1, 2),
    listOf(3, 4),
    listOf(5)
)

val flattened = nested.flatMap { it }

println(flattened)

Output:

[1, 2, 3, 4, 5]

Transform while flattening

val words = listOf("hi", "cat", "dog")

val letters = words.flatMap { word ->
    word.toList()
}

println(letters)

Output:

[h, i, c, a, t, d, o, g]

Each word becomes a list of characters, and flatMap combines them into one list.


Example with objects

data class Department(
    val name: String,
    val employees: List<String>
)

val departments = listOf(
    Department("Engineering", listOf("Alice", "Bob")),
    Department("HR", listOf("Carol"))
)

val allEmployees = departments.flatMap { department ->
    department.employees
}

println(allEmployees)

Output:

[Alice, Bob, Carol]

Transform nested values

data class Order(
    val id: Int,
    val items: List<String>
)

val orders = listOf(
    Order(1, listOf("Book", "Pen")),
    Order(2, listOf("Laptop"))
)

val itemDescriptions = orders.flatMap { order ->
    order.items.map { item ->
        "Order ${order.id}: $item"
    }
}

println(itemDescriptions)

Output:

[Order 1: Book, Order 1: Pen, Order 2: Laptop]

Here:

  1. Each Order is transformed into a List<String>
  2. flatMap flattens all those lists into one List<String>

map vs flatMap

Using map:

val result = orders.map { order ->
    order.items
}

Result type:

List<List<String>>

Using flatMap:

val result = orders.flatMap { order ->
    order.items
}

Result type:

List<String>

Rule of thumb

Use:

map

when each input becomes one output.

Use:

flatMap

when each input becomes many outputs, and you want a single flattened result.

val users = listOf(
    User("Alice", listOf("admin", "editor")),
    User("Bob", listOf("viewer"))
)

val roles = users.flatMap { it.roles }

Result:

[admin, editor, viewer]

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.