LoginSignup
0
0

More than 1 year has passed since last update.

Kotlin KoansでKotlin入門 第27回:Max min

Posted at

はじめに

公式の問題集「Kotlin Koans」を解きながらKotlinを学習します。

過去記事はこちら

問題

Max min

Aggregate operationsについて学びます。
2つの関数を実装します。

  • 最初の関数は、ショップで最も多くの注文を出した顧客を返すこと。
  • 2つ目は、指定された顧客が注文した中で最も高価な商品を返すことです。

関数maxOrNull、minOrNull、maxByOrNull、minByOrNullが役に立つかもしれません。

listOf(1, 42, 4).maxOrNull() == 42
listOf("a", "ab").minByOrNull(String::length) == "a"

ラムダ式の代わりにcallable references(呼び出し可能な参照)を使用することができます。特に、異なるラムダで発生し、異なる型を持つコールチェーンで役に立ちます。getMostExpensiveProductBy関数をcallable referencesを使用して実装します。

修正前コード.kt
// ショップで最も多くの注文を出した顧客を返す
fun Shop.getCustomerWithMaxOrders(): Customer? =
        TODO()

// 指定された顧客が注文した中で最も高価な商品を返す
fun getMostExpensiveProductBy(customer: Customer): 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
}

問題のポイント

minOrNull() と maxOrNull() はそれぞれ最小の要素と最大の要素を返します。
空のコレクションでは、これらはnullを返します。

fun main() {
    val numbers = listOf(6, 42, 10, 4)

    println("Count: ${numbers.count()}") // Count: 4
    println("Max: ${numbers.maxOrNull()}") // Max: 42
    println("Min: ${numbers.minOrNull()}") // Min: 4
    println("Average: ${numbers.average()}") // Average: 15.5
    println("Sum: ${numbers.sum()}") // Sum: 62
}

また、特定のセレクタ関数やカスタムComparatorによって、最小・最大の要素を取得する機能もあります。

  • maxByOrNull()とminByOrNull()はセレクタ関数を受け取り、その関数が最大または最小の値を返す要素を返します。
  • maxWithOrNull()およびminWithOrNull()はComparatorオブジェクトを取り、そのComparatorに従って最大または最小の要素を返します。
  • maxOfOrNull()、minOfOrNull()はセレクタ関数を受け取り、そのセレクタ自体の最大または最小の戻り値を返します。
  • maxOfWithOrNull() および minOfWithOrNull() は Comparator オブジェクトを取り、その Comparator に従って最大または最小のセレクタの戻り値を返します。
val numbers = listOf(5, 42, 10, 4)
val min3Remainder = numbers.minByOrNull { it % 3 }
println(min3Remainder) // 42

解答例

// ショップで最も多くの注文を出した顧客を返す
fun Shop.getCustomerWithMaxOrders(): Customer? = 
    customers.maxByOrNull { it.orders.size }

// 指定された顧客が注文した中で最も高価な商品を返す
fun getMostExpensiveProductBy(customer: Customer): Product? = 
    customer.orders.flatMap(Order::products).maxByOrNull(Product::price)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0