Отформатируйте Map, деструктурируя записи в заголовке for
Map<String, Int> хранит счётчики слов. Верните по куску word=count на запись, соединённые через ", " — например apple=2, pear=5.
Ограничения: обходите деструктурирующим объявлением в заголовке for (for ((k, v) in counts)); не обращайтесь к entry.key / entry.value. Сохраните собственный порядок обхода map. Пустая map даёт пустую строку.
fun format(counts: Map<String, Int>): String {
// ваш код здесь
}
Допишите реализацию.
Цикл обходит значения Map.Entry и деструктурирует каждую, поэтому k — это component1(), а v — component2(): это operator-расширения stdlib для Map.Entry, так что запись не обязана быть data class. Записи идут в собственном порядке обхода map; пустая map даёт пустую строку.
- ✗Думать, что
Map.Entry— этоdata class, а не интерфейс с расширениямиcomponentN - ✗Считать, что деструктурирующий заголовок
forаллоцируетPairна каждую запись - ✗Ожидать, что порядок записей не определён для любой реализации
Map
- →Как в этом цикле деструктурировать только значение, игнорируя ключ?
- →Какая реализация
Mapгарантирует порядок вставки, на который вы здесь опираетесь?
Решение
Деструктурирующее объявление в заголовке for разворачивает каждую Map.Entry в ключ и значение.
fun format(counts: Map<String, Int>): String {
val parts = mutableListOf<String>()
for ((word, count) in counts) { // component1() / component2()
parts += "$word=$count"
}
return parts.joinToString(", ")
}
Почему это работает
Map.Entry — интерфейс, а не data class. Функции componentN для него объявлены в stdlib как operator-расширения:
operator fun <K, V> Map.Entry<K, V>.component1(): K = key
operator fun <K, V> Map.Entry<K, V>.component2(): V = value
Поэтому деструктуризация доступна любому типу, у которого есть такие operator-функции — сгенерированные (data class) или написанные вручную. Порядок записей задаёт сама реализация map: LinkedHashMap (то, что возвращает mapOf) отдаёт порядок вставки. Пустая map просто не входит в цикл, и joinToString даёт пустую строку.