Kotlin KoansでKotlin入門　第３２回：Getting used to the new style

# はじめに
公式の問題集[「Kotlin Koans」](https://play.kotlinlang.org/koans/overview)を解きながらKotlinを学習します。

過去記事はこちら
- Introduction
  - [第０回：Kotlin Koansについて](https://qiita.com/kosuke1/items/41d192af63485bfc8cb8)
  - [第１回：Simple Functions](https://qiita.com/kosuke1/items/5862a3ece96082a62e67)
  - [第２回：Named arguments](https://qiita.com/kosuke1/items/2af11262852ee41b5da7)
  - [第３回：Default arguments](https://qiita.com/kosuke1/items/16cb8ac780df58dc8054)
  - [第４回：Triple-quoted strings](https://qiita.com/kosuke1/items/52cfeed2c49b0252d40e)
  - [第５回：String templates](https://qiita.com/kosuke1/items/0221bbbc5bc70847be6f)
  - [第６回：Nullable types](https://qiita.com/kosuke1/items/aa96e422c5313b6961bc)
  - [第７回：Nothing type](https://qiita.com/kosuke1/items/1ca0e48820d58c9dfe16)
  - [第８回：Lambdas](https://qiita.com/kosuke1/items/8de74f9491e003127f53)
- Classes
  - [第９回：Data classes](https://qiita.com/kosuke1/items/1be2de1b4406b8d914bf) 
  - [第１０回：Smart casts](https://qiita.com/kosuke1/items/50bdecaa0740eb0e1a17)
  - [第１１回：Sealed classes](https://qiita.com/kosuke1/items/71a4da02fe1e99da5d63)
  - [第１２回：Rename on import](https://qiita.com/kosuke1/items/f11465cc15a94e7589a3)
  - [第１３回：Extension functions](https://qiita.com/kosuke1/items/d4a1da00bc142c297221)
- Conventions
  - [第１４回：Comparison](https://qiita.com/kosuke1/items/e9486d044cae32167f36) 
  - [第１５回：Ranges](https://qiita.com/kosuke1/items/797f049ce5f33b1810c9)
  - [第１６回：For loop](https://qiita.com/kosuke1/items/f5f6eeea41fb89b2a20c)
  - [第１７回：Operators overloading](https://qiita.com/kosuke1/items/9845f98a632121f1493b)
  - [第１８回：Invoke](https://qiita.com/kosuke1/items/7879f83341d169374eb3)
- Collections
  - [第１９回：Collections Introduction](https://qiita.com/kosuke1/items/af91a0bd505cd93a3900) 
  - [第２０回：Sort](https://qiita.com/kosuke1/items/ed9a4b36f8573fc65a8f)
  - [第２１回：Filter map](https://qiita.com/kosuke1/items/45e70bac73706643e40c)
  - [第２２回：All, Any, and other predicates](https://qiita.com/kosuke1/items/daa940bf57e93d198ce4)
  - [第２３回：Associate](https://qiita.com/kosuke1/items/a4d8b0701b6848d43473)
  - [第２４回：Group By](https://qiita.com/drafts/d2279add0e79cbe19f01/edit)
  - [第２５回：Partition](https://qiita.com/kosuke1/items/d2279add0e79cbe19f01)
  - [第２６回：FlatMap](https://qiita.com/kosuke1/items/f08f22de98d736df6e12)
  - [第２７回：Max min](https://qiita.com/kosuke1/items/f2af0574bbc594bbe494)
  - [第２８回：Sum](https://qiita.com/kosuke1/items/477c2fd0886231440d06)
  - [第２９回：Fold](https://qiita.com/kosuke1/items/9b6ca3ab409335897adf)
  - [第３０回：Compound tasks](https://qiita.com/kosuke1/items/66949d40ce744bc696cb)
  - [第３１回：Sequences](https://qiita.com/kosuke1/items/f62212f67bde03298f11)

# 問題
 [Getting used to the new style](https://play.kotlinlang.org/koans/Collections/Getting%20used%20to%20new%20style/Task.kt)

ラムダとコレクションに対する操作を使って、以下のコードを書き換えて簡略化することができます。```doSomethingWithCollectionOldStyle```関数の簡略版である```doSomethingWithCollection```の動作が変わらないように変更します。

```Kotlin
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```関数で行っていることを確認します。
1. groupsByLength の取得
    - 引数の文字列リストを文字列長でグループ化してgroupsByLengthに設定します。
    - groupsByLengthは、キー：文字列長、値：文字列リストになります。
2. maximumSizeOfGroup の取得
    - groupsByLengthの値で要素数が多い文字列リストをmaximumSizeOfGroupとして取得します。
2. group の返却
    - 要素数が多い文字列リストを返却します


上記を行うために必要になる知識を復習します。
## groupBy
[第２４回：Group By](https://qiita.com/kosuke1/items/1815270eb39249f46cfe)
```Kotlin
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
[第２１回：Filter map](https://qiita.com/kosuke1/items/45e70bac73706643e40c)
```Kotlin
val numbers = setOf(1, 2, 3)
println(numbers.map { it * 3 }) // [3, 6, 9]
```

## Max min
[第２７回：Max min](https://qiita.com/kosuke1/items/f2af0574bbc594bbe494)
```Kotlin
listOf(1, 42, 4).maxOrNull() == 42
listOf("a", "ab").minByOrNull(String::length) == "a"
```

# 解答例
```Kotlin
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 }
}
```