はじめに
公式の問題集「Kotlin Koans」を解きながらKotlinを学習します。
過去記事はこちら
- Introduction
- Classes
- Conventions
- Collections
問題
ラムダとコレクションに対する操作を使って、以下のコードを書き換えて簡略化することができます。doSomethingWithCollectionOldStyle
関数の簡略版であるdoSomethingWithCollection
の動作が変わらないように変更します。
fun doSomethingWithCollectionOldStyle(
collection: Collection<String>
): Collection<String>? {
val groupsByLength = mutableMapOf<Int, MutableList<String>>()
for (s in collection) {
var strings: MutableList<String>? = groupsByLength[s.length]
if (strings == null) {
strings = mutableListOf()
groupsByLength[s.length] = strings
}
strings.add(s)
}
var maximumSizeOfGroup = 0
for (group in groupsByLength.values) {
if (group.size > maximumSizeOfGroup) {
maximumSizeOfGroup = group.size
}
}
for (group in groupsByLength.values) {
if (group.size == maximumSizeOfGroup) {
return group
}
}
return null
}
修正前コード.kt
fun doSomethingWithCollection(collection: Collection<String>): Collection<String>? {
val groupsByLength = collection.groupBy { s -> TODO() }
val maximumSizeOfGroup = groupsByLength.values.map { group -> TODO() }.maxOrNull()
return groupsByLength.values.firstOrNull { group -> TODO() }
}
問題のポイント
これまでの復習の問題になります。
doSomethingWithCollectionOldStyle
関数で行っていることを確認します。
- groupsByLength の取得
- 引数の文字列リストを文字列長でグループ化してgroupsByLengthに設定します。
- groupsByLengthは、キー:文字列長、値:文字列リストになります。
- maximumSizeOfGroup の取得
- groupsByLengthの値で要素数が多い文字列リストをmaximumSizeOfGroupとして取得します。
- group の返却
- 要素数が多い文字列リストを返却します
上記を行うために必要になる知識を復習します。
groupBy
val words = listOf("a", "abc", "ab", "def", "abcd")
val byLength: Map<Int, List<String>> = words.groupBy { it.length }
println(byLength.toString()) // {1=[a], 3=[abc, def], 2=[ab], 4=[abcd]}
map
val numbers = setOf(1, 2, 3)
println(numbers.map { it * 3 }) // [3, 6, 9]
Max min
listOf(1, 42, 4).maxOrNull() == 42
listOf("a", "ab").minByOrNull(String::length) == "a"
解答例
fun doSomethingWithCollection(collection: Collection<String>): Collection<String>? {
val groupsByLength = collection.groupBy { s -> s.length }
val maximumSizeOfGroup = groupsByLength.values.map { group -> group.size }.maxOrNull()
return groupsByLength.values.firstOrNull { group -> group.size == maximumSizeOfGroup }
}