【Kotlin練習問題】コレクション グルーピング(groupBy)

Kotlin

groupBy()でグルーピングする

Kotlinの標準ライブラリにはコレクションの要素をグルーピングするための拡張関数が用意されています。基本的な関数はgroupBy()で、ラムダ関数を引数にとり、Mapを返します。

返されたMapではそれぞれのキーはラムダ関数の結果で、値にはそのラムダ関数の結果に対応する要素のリストが入ります。使用例としては、文字列を最初の文字ごとにグルーピングしたりする際などに使われます。

またgroupBy()関数は2つ目の引数に変換関数であるラムダ関数を設定して呼び出すこともできます。この場合の返り値のMapでは、keySelector関数によって生成された値がキーに、変換関数の結果が値にセットされます。

例)

val numbers = listOf("one", "two", "three", "four", "five")

println(numbers.groupBy { it.first().uppercase() })
//{O=[one], T=[two, three], F=[four, five]}
println(numbers.groupBy(keySelector = { it.first() }, valueTransform = { it.uppercase() }))
//{o=[ONE], t=[TWO, THREE], f=[FOUR, FIVE]}

問題

groupByを使ってcustomerをcityごとに分類したリストを格納するマップを返す関数を実装してください。

なお、全ての関連するクラスはShop.ktに含まれています。

問題コード:

fun Shop.groupCustomersByCity(): Map<City, List<Customer>> =
        TODO()

Shop.kt:

data class Shop(val name: String, val customers: List<Customer>)
​
data class Customer(val name: String, val city: City, val orders: List<Order>) {
    override fun toString() = "$name from ${city.name}"
}
​
data class Order(val products: List<Product>, val isDelivered: Boolean)
​
data class Product(val name: String, val price: Double) {
    override fun toString() = "'$name' for $price"
}
​
data class City(val name: String) {
    override fun toString() = name
}

答え

// Build a map that stores the customers living in a given city
fun Shop.groupCustomersByCity(): Map<City, List<Customer>> =
        customers.groupBy { it.city }

[解説]

引数にit.cityを指定することでcustomers中のそれぞれのcustomerのcityプロパティで分類しています。

答え

その他の問題はこちらからどうぞ。

おすすめ書籍

Kotlinの文法をまず学びたい!という方には以下の書籍がおすすめです。Kotlinは日本語書籍がまだ豊富とは言えない状況ですが、細かく解説されており、Kotlin入門者のかたでもつまずくことなく学習できると思います。

実際にアプリを作りながら覚えていきたい!という方には以下もお勧めです。はじめに上の書籍で文法をさらっと学んでから取り組むのがお勧めです。

プロフィール

プロフィール
コードラボJP

大学卒業後SEに就職、現在は退職しフリーランスとして活動中。
『初心者でも挫折せずに一人でプログラミングを学べる』をモットーに、コードラボJPを開設
お問い合わせ等はcodelabsjp@gmail.comまで

コードラボJPをフォローする
タイトルとURLをコピーしました