[毎日Kotlin] Day25. All, Any and other predicates

2018.02.21

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

はじめに

毎日Kotlinシリーズです。

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

問題

All Any and other predicates | Try Kotlin

Implement all the functions below using all, any, count, find.

val numbers = listOf(-1, 0, 2)
val isZero: (Int) -> Boolean = { it == 0 }
numbers.any(isZero) == true
numbers.all(isZero) == false
numbers.count(isZero) == 1
numbers.find { it > 0 } == 2
// Return true if all customers are from the given city
fun Shop.checkAllCustomersAreFrom(city: City): Boolean = TODO()

// Return true if there is at least one customer from the given city
fun Shop.hasCustomerFrom(city: City): Boolean = TODO()

// Return the number of customers from the given city
fun Shop.countCustomersFrom(city: City): Int = TODO()

// Return a customer who lives in the given city, or null if there is none
fun Shop.findAnyCustomerFrom(city: City): Customer? = TODO()

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 Shop.checkAllCustomersAreFrom(city: City): Boolean = customers.all { it.city == city }

fun Shop.hasCustomerFrom(city: City): Boolean = customers.any { it.city == city }

fun Shop.countCustomersFrom(city: City): Int = customers.count { it.city == city }

fun Shop.findAnyCustomerFrom(city: City): Customer? = customers.find { it.city == city }

allは、全部条件にあうかチェックします。1つでも条件あわないとfalseになります。条件部分をラムダでかきます。{ it.city == city }

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

fun all(shop: Shop, city: City): Boolean {
    for (customer in shop.customers) {
        if (!(customer.city == city)) {
            return false
        }
    }
    return true
}

anyは、1つでも条件にあうかチェックします。条件部分をラムダでかきます。{ it.city == city }

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

fun any(shop: Shop, city: City): Boolean {
    for (customer in shop.customers) {
        if (customer.city == city) {
            return true
        }
    }
    return false
}

countは、条件にあった数を計算します。条件部分をラムダでかきます。{ it.city == city }

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

fun count(shop: Shop, city: City): Int {
    var count = 0
    for (customer in shop.customers) {
        if (customer.city == city) {
            count++
        }
    }
    return count
}

findは、条件にあった最初の要素を返します。条件に一致しない場合はnullを返します。条件部分をラムダでかきます。{ it.city == city }

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

fun find(shop: Shop, city: City): Customer? {
    for (customer in shop.customers) {
        if (customer.city == city) {
            return customer
        }
    }
    return null
}

あとがき

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