Format a Map by destructuring its entries in the for header
A Map<String, Int> holds word counts. Return one word=count piece per entry, joined by ", " — for example apple=2, pear=5.
Constraints: iterate with a destructuring declaration in the for header (for ((k, v) in counts)); do not read entry.key / entry.value. Keep the map's own iteration order. An empty map returns an empty string.
fun format(counts: Map<String, Int>): String {
// your code here
}
Write the implementation.
The loop iterates Map.Entry values and destructures each, so k is component1() and v is component2() — stdlib operator extensions on Map.Entry, so the entry need not be a data class. Entries follow the map's own iteration order; an empty map gives an empty string.
- ✗Thinking
Map.Entryis adata classrather than an interface withcomponentNextensions - ✗Assuming a destructuring
forheader allocates aPairper entry - ✗Expecting the entry order to be undefined for every
Mapimplementation
- →How would you destructure only the value and ignore the key in that loop?
- →Which
Mapimplementation guarantees the insertion order you rely on here?
Solution
A destructuring declaration in the for header unpacks every Map.Entry into a key and a value.
fun format(counts: Map<String, Int>): String {
val parts = mutableListOf<String>()
for ((word, count) in counts) { // component1() / component2()
parts += "$word=$count"
}
return parts.joinToString(", ")
}
Why it works
Map.Entry is an interface, not a data class. Its componentN functions are declared in the stdlib as operator extensions:
operator fun <K, V> Map.Entry<K, V>.component1(): K = key
operator fun <K, V> Map.Entry<K, V>.component2(): V = value
So destructuring is open to any type that declares such operator functions — generated (a data class) or hand-written. Entry order is the map implementation's own: LinkedHashMap, which mapOf returns, keeps insertion order. An empty map never enters the loop, and joinToString gives an empty string.