はじめに
公式の問題集「Kotlin Koans」を解きながらKotlinを学習します。
過去記事はこちら
- Introduction
- Classes
- Conventions
- Collections
問題
Compound tasks
2つの機能を実装します。
- 最初の関数は,顧客が注文したすべての納品済み製品の中から,最も高価な製品を見つけます。Order.isDeliveredフラグを使用します。
- 2つ目は、商品が注文された回数をカウントすることです。顧客は同じ製品を何度も注文する可能性があることに注意してください。
前回説明したKotlin標準ライブラリの関数を使用します。
前のタスクで定義したCustomer.getOrderedProducts()関数が使えます。(その実装をコピーしてください)
修正前コード.kt
// Find the most expensive product among all the delivered products
// ordered by the customer. Use `Order.isDelivered` flag.
fun findMostExpensiveProductBy(customer: Customer): Product? {
TODO()
}
// Count the amount of times a product was ordered.
// Note that a customer may order the same product several times.
fun Shop.getNumberOfTimesProductWasOrdered(product: Product): Int {
TODO()
}
fun Customer.getOrderedProducts(): List<Product> =
/* 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
}
問題のポイント
新しい要素は特になく、これまでの応用で実装できます。
解答例
// Find the most expensive product among all the delivered products
// ordered by the customer. Use `Order.isDelivered` flag.
// 顧客が注文したすべての納品済み製品の中から,最も高価な製品を見つけます
fun findMostExpensiveProductBy(customer: Customer): Product? {
return customer
.orders
.filter(Order::isDelivered)
.flatMap(Order::products)
.maxByOrNull(Product::price)
}
// Count the amount of times a product was ordered.
// Note that a customer may order the same product several times.
// 商品が注文された回数をカウントすることです。
// 顧客は同じ製品を何度も注文する可能性があることに注意してください。
fun Shop.getNumberOfTimesProductWasOrdered(product: Product): Int {
return customers
.flatMap(Customer::getOrderedProducts)
.count { it == product }
}
// 与えられた顧客が注文したすべての製品を返す
fun Customer.getOrderedProducts(): List<Product> = orders.flatMap(Order::products)
// getOrderedProducts()関数を使用しない場合はこのような感じになります
fun Shop.getNumberOfTimesProductWasOrdered(product: Product): Int {
return customers
.flatMap(Customer::orders) // List<Order>
.flatMap(Order::products) // List<Product>
.count { it == product }
}