この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
毎日Kotlinシリーズです。
このシリーズを初めての方はこちらです。「毎日Kotlin」はじめました | Developers.IO
問題
Implement extension functions Shop.getCitiesCustomersAreFrom() and Shop.getCustomersFrom() using functions map and filter.
val numbers = listOf(1, -1, 2)
numbers.filter { it > 0 } == listOf(1, 2)
numbers.map { it * it } == listOf(1, 1, 4)
// Return the set of cities the customers are from
fun Shop.getCitiesCustomersAreFrom(): Set<City> = TODO()
// Return a list of the customers who live in the given city
fun Shop.getCustomersFrom(city: City): List<Customer> = TODO()
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
}
狙い
ここで考えて欲しい問題の意図はなんだろうか?
コレクションを処理する便利関数はたくさんあるので使って覚えよう。
解答例
fun Shop.getCitiesCustomersAreFrom(): Set<City> = customers.map { it.city }.toSet()
fun Shop.getCustomersFrom(city: City): List<Customer> = customers.filter { it.city == city }
mapは、コレクションの要素1つずつ別なものに変換するイメージです。ラムダの中に変換の処理を書きます。{ it.city }
customer1つ1つを -> city に変換していきます。
わかりやすい等価コードを書きました。
fun map(shop: Shop): Set<City> {
val list = mutableListOf<City>()
for (customer in shop.customers) {
list.add(customer.city)
}
return list.toSet()
}
filterは、コレクションから必要なものだけを残すイメージです。ラムダでいるか、いらないか判断する処理を書きます。trueなら残す。{ it.city == city }
customer1つ1つをいる、いらないをしていき、いるものリストだけを作ります。
わかりやすい等価コードを書きました。
fun filter(shop: Shop, city: City): List<City> {
val list = mutableListOf<City>()
for (customer in shop.customers) {
if (customer.city == city) {
list.add(customer.city)
}
}
return list
}
あとがき
Day25.でまたお会いしましょう。