【Kotlin練習問題】コレクション PartitionによるフィルタリングとDestructuring declaration(分解宣言)

Partitionとは

Partition(パーティション)とは日本語で「分割」や「仕切り」を意味する英語です。

リストなどのコレクションを特定の条件下でフィルタリングすることはよくありますが、フィルタリングのための関数がKotlinには事前に用意されちえます。その一つが今回紹介するpartition()です。

partition()は引数に渡された条件式やラムダ関数に合致しない要素を別のリストとしてキープしてくれます。したがって、返り値はListのPairになります。一つ目のリストには条件に合致した要素が入っており、二つ目にはそれ以外の要素が入っています。

val numbers = listOf("one", "two", "three", "four")
val (match, rest) = numbers.partition { it.length > 3 }

println(match)  //[three, four]
println(rest)   //[one, two]

Destructuring declaration(分解宣言)

Partitionの説明で挙げた上のコードの中には

val (match, rest) = numbers.partition { it.length > 3 }

という部分があります。これはDestructuring declaration(分解宣言)と呼ばれるもので、一つのオブジェクトの複数の変数に分解するために行っているものです。

例えば”名前”と”年齢”という属性を含んでいる”人間”というものを定義したいときに、いちいち一つずつ定義するのではなく、分解宣言を用いて以下のように表すことができます。

val (name, age) = person

ここでは一度に二つの変数(name, age)を宣言しており、それぞれ独立して使用することもできます。

上のコードはコンパイル時に以下のように解釈されます。

val name = person.component1()
val age = person.component2()

分解宣言の右辺にはcomponent関数を呼び出せる範囲内であればなんでも置くことができます。ですので、component3()やcomponent4()なども場合によってはあり得ます。

Point:componentN()関数を分解宣言で使用できるようにするためにはoperatorキーワードでマーキングされている必要があります。

問題

patitionを使って注文した商品の中でまだ配送されていない(undelivered)商品の数のほうが多い顧客を返す関数を実装してください。

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

問題コード:

//未配送の商品の方が多い顧客を返す
fun Shop.getCustomersWithMoreUndeliveredOrders(): Set<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
}
[expander_maker id=”1″ more=”ヒント” less=”非表示”]

ヒント

deliveredとundeliveredごとにリストを分ける必要があります。その際に分解宣言を使って代入します。分解宣言は以下のように使います。

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

positive == listOf(1, 3, 2)
negative == listOf(-4, -11)
[/expander_maker] [expander_maker id=”1″ more=”答え” less=”非表示”]

答え

//未配送の商品の方が多い顧客を返す
fun Shop.getCustomersWithMoreUndeliveredOrders(): Set<Customer> = 
    customers.filter {
        val (delivered, undelivered) = it.orders.partition { it.isDelivered }
        undelivered.size > delivered.size
    }.toSet()

[/expander_maker]

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

完全無料で通えるプログラミングスクール

プログラミング学習はどうしても一人だとつまづいてしまう時がきます。調べればわかることも少なくないですが、最初のうちは調べ方もわからないことが多いため、あまり効率的ではありません。

効率的かつ挫折せずにプログラミングを学習したい方はスクールを検討してみるのも一つの手です。

中には無料で通えるスクールや、就職保証をしてくれるスクールなどもあるので、きっとあなたの目的に応じて最適のスクールが見つかります!以下の記事で評判がよく特におすすめのスクールをいくつかピックアップしているので、スクール選びで後悔したくない方は御覧ください!

https://codelabsjp.net/best-programming-school/

おすすめ書籍

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

[itemlink post_id=”1743″]

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

[itemlink post_id=”1745″]