はじめに
公式の問題集「Kotlin Koans」を解きながらKotlinを学習します。
過去記事はこちら
- Introduction
- Classes
- Conventions
- Collections
問題
Filter map
map関数とfilter関数を使って、以下の拡張関数を実装してください。
- 顧客の出身地が異なるすべての都市を検索する
- 指定された都市に住んでいる顧客を検索する
val numbers = listOf(1, -1, 2)
numbers.filter { it > 0 } == listOf(1, 2)
numbers.map { it * it } == listOf(1, 1, 4)
修正前のコード.kt
// Find all the different cities the customers are from
fun Shop.getCustomerCities(): Set<City> =
TODO()
// Find the customers living in a given city
fun Shop.getCustomersFrom(city: City): List<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
}
問題のポイント
map
マッピング変換は、別のコレクションの要素に対する関数の結果からコレクションを作成します。
さらに要素のインデックスを引数として使う変換を行うには、 mapIndexed()を使用します。
val numbers = setOf(1, 2, 3)
println(numbers.map { it * 3 }) // ==>[3, 6, 9]
println(numbers.mapIndexed { idx, value -> value * idx }) // ==>[0, 2, 6]
Filter by predicate
基本的なフィルタリング関数は、filter()です。述語を指定して呼び出すと、 filter()はそれにマッチするコレクション要素を返します。ListとSetの両方について、結果のコレクションはListになり、Mapについては同様にMapになります。
val numbers = listOf("one", "two", "three", "four")
val longerThan3 = numbers.filter { it.length > 3 }
println(longerThan3) // ==>[three, four]
val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
val filteredMap = numbersMap.filter { (key, value) -> key.endsWith("1") && value > 10}
println(filteredMap) // ==>{key11=11}
解答例
// 顧客の出身地が異なるすべての都市を検索する
fun Shop.getCustomerCities(): Set<City> = customers.map { it.city }.toSet()
// 指定された都市に住んでいる顧客を検索する
fun Shop.getCustomersFrom(city: City): List<Customer> = customers.filter { it.city == city }