【Kotlin練習問題】コレクション sumByで合計を求める

Kotlin

sumByによって指定した式の合計を求める

上の記事でも解説した通り、リストの要素の合計はsum()関数で取得することができます。

listOf(1, 5, 3).sum() == 9

下のコードはリストに含まれる要素の文字列の文字数の合計を求めています。

listOf("a", "b", "cc").sumBy { it.length } == 4

このように、要素自身が数値なのではなく、文字の長さなど要素のある性質を数値化して合計処理をさせたい場合はsumBy()関数を使って、ラムダ式を渡すことで求めることができます。

Double型で返したいときには同じようにしてsumByDouble()を使うことができます。

問題

引数に渡した顧客によって注文された商品の合計金額を計算させて、顧客が使った合計金額を求める関数を実装してください。ただしそれぞれの商品は注文される度にカウントされるものとします。

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

問題コード:

// 引数に渡した顧客によって注文された商品の合計金額を返す
fun moneySpentBy(customer: Customer): Double =
        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
}

答え

// 引数に渡した顧客によって注文された商品の合計金額を返す
fun moneySpentBy(customer: Customer): Double =
    customer.orders.flatMap { it.products }.sumByDouble { it.price }

[解説]

今回はDouble型を返したいのでsumByDoubleを使っています。

順序として、引数に渡されたcustomerからordersを取り出し、それにflatMapを使ってネストの階層を平坦にしています。flatMapの実行結果の例を以下に載せておきます

val list = listOf(listOf("a", "b"), listOf("c", "d"), listOf("e", "f"))

list.flatMap { it } //[a, b, c, d, e, f]

その後、flatMapで平坦にしたproductのpriceの合計を求める処理をsumByDoubleで行っています。

答え

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

おすすめ書籍

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

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

プロフィール

プロフィール
コードラボJP

大学卒業後SEに就職、現在は退職しフリーランスとして活動中。
『初心者でも挫折せずに一人でプログラミングを学べる』をモットーに、コードラボJPを開設
お問い合わせ等はcodelabsjp@gmail.comまで

コードラボJPをフォローする
タイトルとURLをコピーしました