[毎日Kotlin] Day30. Partition

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

毎日Kotlinシリーズです。

このシリーズを初めての方はこちらです。「毎日Kotlin」はじめました | Developers.IO

問題

Partition | Try Kotlin

Implement Shop.getCustomersWithMoreUndeliveredOrdersThanDelivered() using partition.

val numbers = listOf(1, 3, -4, 2, -11)
val (positive, negative) = numbers.partition { it > 0 }
positive == listOf(1, 3, 2)
negative == listOf(-4, -11)

Note that destructuring declaration syntax is used in this example.

// Return customers who have more undelivered orders than delivered
fun Shop.getCustomersWithMoreUndeliveredOrdersThanDelivered(): Set<Customer> = TODO()

狙い

ここで考えて欲しい問題の意図はなんだろうか?

コレクションを処理する便利関数はたくさんあるので使って覚えよう。

解答例

fun Shop.getCustomersWithMoreUndeliveredOrdersThanDelivered(): Set<Customer> = customers.filter {
    val (delivered, undelivered) = it.orders.partition { it.isDelivered }
    undelivered.size > delivered.size
}.toSet()

partitionは、コレクションの中身を2分割してします。条件をラムダ式で書きます。{ it.isDelivered }

filterはtrueのリストだけですがfalseのリストも欲しいときには便利かもしれません。

わかりやすい等価コードを書きました。

fun partition(customer: Customer): Pair<List<Order>, List<Order>> {
    val isDeliveredList = mutableListOf<Order>()
    val isNotDeliveredList = mutableListOf<Order>()
    for (order in customer.orders) {
        if (order.isDelivered) {
            isDeliveredList.add(order)
        } else {
            isNotDeliveredList.add(order)
        }
    }
    return isDeliveredList to isNotDeliveredList
}

余談で、Pairが要素ごとに分解できるのは、KotlinのPairData classで定義されている。Data classcomponentNが実装されてるからです。

Pair - Kotlin Programming Language

Destructuring Declarations - Kotlin Programming Language

toはただのKotlinの拡張関数で、簡単にPairを作れちゃう。便利やつです。

to - Kotlin Programming Language

あとがき

Day31.でまたお会いしましょう。