はじめに
公式の問題集「Kotlin Koans」を解きながらKotlinを学習します。
過去記事はこちら
- Introduction
- Classes
- Conventions
- Collections
問題
All, Any, and other predicates
Test predicatesと条件による要素の取得について学びます。
all, any, count, find を使って以下の関数を実装してください。
- checkAllCustomersAreFromは、すべての顧客が指定された都市の出身である場合にtrue を返す必要があります。
- hasCustomerFromは、指定された都市からの顧客が少なくとも一人いるかどうかをチェックする必要があります。
- countCustomersFrom は、指定された都市からの顧客の人数を返します。
- findCustomerFrom は、指定された都市に住んでいる顧客を返すか、 存在しない場合は null を返します。
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
修正前コード.kt
// すべての顧客が指定された都市の出身である場合、true を返します
fun Shop.checkAllCustomersAreFrom(city: City): Boolean =
TODO()
// 指定された都市からの顧客が少なくとも一人いるかどうかをチェック
fun Shop.hasCustomerFrom(city: City): Boolean =
TODO()
// 指定された都市からの顧客の人数を返します
fun Shop.countCustomersFrom(city: City): Int =
TODO()
// 指定された都市に住んでいる顧客を返すか、 存在しない場合は null を返します
fun Shop.findCustomerFrom(city: City): 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
}
問題のポイント
Test predicates
- any() は、少なくとも一つの要素が与えられた述語にマッチすれば、trueを返します。
- none() は、与えられた述語に合致する要素がない場合にtrueを返します。
- all()は、すべての要素が与えられた述語にマッチする場合、trueを返します。all()は、空のコレクションに対して、任意の有効な述語で呼ばれると、真を返すことに 注意してください。
val numbers = listOf("one", "two", "three", "four")
println(numbers.any { it.endsWith("e") }) // true
println(numbers.none { it.endsWith("a") }) // true
println(numbers.all { it.endsWith("e") }) // false
println(emptyList<Int>().all { it > 5 }) // true
解答例
// すべての顧客が指定された都市の出身である場合、true を返します
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 }
// 指定された都市に住んでいる顧客を返すか、 存在しない場合は null を返します
fun Shop.findCustomerFrom(city: City): Customer? =
customers.find { it.city == city }