In Kotlin, destructuring lets you unpack values from an object into separate variables.
It is commonly used with:
PairMap.Entry- loops over maps
- lambda parameters
Destructuring a Pair
A Pair<A, B> contains two values: first and second.
val pair = "Alice" to 25
val (name, age) = pair
println(name) // Alice
println(age) // 25
This is equivalent to:
val name = pair.first
val age = pair.second
You can also create a Pair explicitly:
val pair = Pair("Kotlin", 2.1)
val (language, version) = pair
println(language) // Kotlin
println(version) // 2.1
Destructuring map entries in a loop
When you iterate over a map, each item is a Map.Entry<K, V>. Kotlin lets you destructure it into key and value:
val ages = mapOf(
"Alice" to 25,
"Bob" to 30
)
for ((name, age) in ages) {
println("$name is $age years old")
}
Here:
(name, age)
means:
name = entry.key
age = entry.value
Destructuring in lambdas
You can destructure map entries inside lambda parameters too:
val scores = mapOf(
"Alice" to 90,
"Bob" to 85,
"Charlie" to 95
)
scores.forEach { (name, score) ->
println("$name scored $score")
}
You can also use it with operations like map, filter, and sortedBy:
val passingStudents = scores.filter { (_, score) ->
score >= 90
}
println(passingStudents) // {Alice=90, Charlie=95}
Ignoring values with _
If you only need one part of the destructured value, use _ for the part you want to ignore.
val user = "Alice" to 25
val (name, _) = user
println(name) // Alice
With a map:
val ages = mapOf(
"Alice" to 25,
"Bob" to 30
)
for ((name, _) in ages) {
println(name)
}
Or if you only need values:
for ((_, age) in ages) {
println(age)
}
Destructuring mutable maps
Destructuring works the same way with mutable maps:
val inventory = mutableMapOf(
"Apples" to 10,
"Oranges" to 5
)
for ((item, count) in inventory) {
println("$item: $count")
}
If you want to update values, use the key:
for ((item, count) in inventory) {
inventory[item] = count + 1
}
println(inventory) // {Apples=11, Oranges=6}
Important detail: destructuring depends on componentN() functions
Destructuring works when a type provides functions like:
component1()
component2()
Pair has:
component1() // first
component2() // second
Map entries support destructuring as:
component1() // key
component2() // value
So this:
val (key, value) = "id" to 123
is essentially:
val pair = "id" to 123
val key = pair.component1()
val value = pair.component2()
Quick summary
val pair = "Alice" to 25
val (name, age) = pair
val map = mapOf(
"Alice" to 25,
"Bob" to 30
)
for ((key, value) in map) {
println("$key -> $value")
}
map.forEach { (key, value) ->
println("$key -> $value")
}
Use destructuring when it makes key-value or pair-based code easier to read.
