How do I use associateBy, partition, and zip in Kotlin?

In Kotlin, associateBy, partition, and zip are collection operations that help transform or split collections.

associateBy

associateBy creates a Map from a collection by choosing a key for each element.

data class User(val id: Int, val name: String)

val users = listOf(
    User(1, "Alice"),
    User(2, "Bob"),
    User(3, "Charlie")
)

val usersById = users.associateBy { user -> user.id }

println(usersById)

Output:

{
  1=User(id=1, name=Alice),
  2=User(id=2, name=Bob),
  3=User(id=3, name=Charlie)
}

You can also choose both the key and the value:

val namesById = users.associateBy(
    keySelector = { it.id },
    valueTransform = { it.name }
)

println(namesById)

Output:

{1=Alice, 2=Bob, 3=Charlie}

If multiple elements produce the same key, the last one wins:

val words = listOf("one", "two", "three", "ten")

val byFirstLetter = words.associateBy { it.first() }

println(byFirstLetter)

Output:

{o=one, t=ten}

Here, "ten" replaces "two" and "three" for key 't'.


partition

partition splits a collection into two lists based on a predicate.

It returns a Pair<List<T>, List<T>>:

  • first contains elements where the predicate is true
  • second contains elements where the predicate is false
val numbers = listOf(1, 2, 3, 4, 5, 6)

val result = numbers.partition { it % 2 == 0 }

val evens = result.first
val odds = result.second

println(evens)
println(odds)

Output:

[2, 4, 6]
[1, 3, 5]

Commonly, you destructure the result:

val (evens, odds) = numbers.partition { it % 2 == 0 }

println(evens)
println(odds)

Example with objects:

data class Task(val title: String, val done: Boolean)

val tasks = listOf(
    Task("Write tests", true),
    Task("Fix bug", false),
    Task("Deploy", false)
)

val (completed, pending) = tasks.partition { it.done }

println(completed)
println(pending)

zip

zip combines two collections element by element.

val names = listOf("Alice", "Bob", "Charlie")
val ages = listOf(25, 30, 35)

val people = names.zip(ages)

println(people)

Output:

[(Alice, 25), (Bob, 30), (Charlie, 35)]

The result is a List<Pair<A, B>>.

You can destructure each pair:

for ((name, age) in names.zip(ages)) {
    println("$name is $age years old")
}

Output:

Alice is 25 years old
Bob is 30 years old
Charlie is 35 years old

You can also provide a transform function:

val descriptions = names.zip(ages) { name, age ->
    "$name is $age years old"
}

println(descriptions)

Output:

[Alice is 25 years old, Bob is 30 years old, Charlie is 35 years old]

If the collections have different sizes, zip stops at the shorter one:

val letters = listOf("A", "B", "C")
val numbers = listOf(1, 2)

println(letters.zip(numbers))

Output:

[(A, 1), (B, 2)]

Quick comparison

Function Purpose Result
associateBy Turns a collection into a Map Map<K, T> or Map<K, V>
partition Splits a collection into two lists Pair<List<T>, List<T>>
zip Combines two collections element by element List<Pair<A, B>> or List<R>

Example using all three:

data class Person(val id: Int, val name: String, val age: Int)

val people = listOf(
    Person(1, "Alice", 17),
    Person(2, "Bob", 21),
    Person(3, "Charlie", 30)
)

val peopleById = people.associateBy { it.id }

val (adults, minors) = people.partition { it.age >= 18 }

val namesWithAges = people.map { it.name }.zip(people.map { it.age })

println(peopleById)
println(adults)
println(minors)
println(namesWithAges)

Use:

  • associateBy when you want lookup by a key
  • partition when you want to split a list into matching and non-matching groups
  • zip when you want to pair two collections by position

Leave a Reply

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