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″]

groupBy()でグルーピングする

Kotlinの標準ライブラリにはコレクションの要素をグルーピングするための拡張関数が用意されています。基本的な関数はgroupBy()で、ラムダ関数を引数にとり、Mapを返します。

返されたMapではそれぞれのキーはラムダ関数の結果で、値にはそのラムダ関数の結果に対応する要素のリストが入ります。使用例としては、文字列を最初の文字ごとにグルーピングしたりする際などに使われます。

またgroupBy()関数は2つ目の引数に変換関数であるラムダ関数を設定して呼び出すこともできます。この場合の返り値のMapでは、keySelector関数によって生成された値がキーに、変換関数の結果が値にセットされます。

例)

val numbers = listOf("one", "two", "three", "four", "five")

println(numbers.groupBy { it.first().uppercase() })
//{O=[one], T=[two, three], F=[four, five]}
println(numbers.groupBy(keySelector = { it.first() }, valueTransform = { it.uppercase() }))
//{o=[ONE], t=[TWO, THREE], f=[FOUR, FIVE]}

問題

groupByを使ってcustomerをcityごとに分類したリストを格納するマップを返す関数を実装してください。

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

問題コード:

fun Shop.groupCustomersByCity(): Map<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
}
[expander_maker id=”1″ more=”答え” less=”非表示”]

答え

// Build a map that stores the customers living in a given city
fun Shop.groupCustomersByCity(): Map<City, List<Customer>> =
        customers.groupBy { it.city }

[解説]

引数にit.cityを指定することでcustomers中のそれぞれのcustomerのcityプロパティで分類しています。

[/expander_maker]

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

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

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

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

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

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

おすすめ書籍

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

[itemlink post_id=”1743″]

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

[itemlink post_id=”1745″]

Association変換でMapを作成する

Association(=関連)変換を使うとコレクションの要素と、その要素に関連付けされた特定の値から新たにMapを作成することができます。

Association変換にはいくつか種類があり、使い分けることで要素自体をキーにすることも値にすることもできます。具体的にはassociateWith()associateBy()associate()の3つがあります。それぞれ確認していきましょう。

associateWith()

一番基本の関数はassociateWith()です。これはもとのコレクションの要素がキーとなり、引数に与えられた変換関数によって生成された値がMapの値になります。等しい要素がある場合、最後の要素がMapに残存します。

val numbers = listOf("one", "two", "three", "four")
println(numbers.associateWith { it.length })
//{one=3, two=3, three=5, four=4}

上記コードでは引数に it.length を渡しているので、”one”, “two”, “three”, “four”それぞれの文字列の長さが値になるMapを返します。

associateBy()

もとのコレクションの要素を値とするMapを作るためにはassociateBy()を使用します。

これは要素の値に基づいたキーを返す関数を引数にとり、Mapを作成します。等しい要素がある場合、最後の要素がMapに残存します。

val numbers = listOf("one", "two", "three", "four")
println(numbers.associateBy { it.first().uppercaseChar() })
//{O=one, T=three, F=four}

引数に渡されたit.first().uppercaseChar()は、it.first()でそれぞれの要素の最初の一文字を指定し、uppercaseChar()でそれらを大文字に変換しています。

出力結果ではもとのリストの要素が値になっていることがわかります。

associate()

Another way to build maps in which both keys and values are somehow produced from collection elements is the function associate(). It takes a lambda function that returns a Pair: the key and the value of the corresponding map entry.

キーと値がの両方がなんらかの形でもとのコレクションの要素から生成される場合はassociate()を使います。これは対応するMapのエントリのキーと値のPairを返すラムダ関数を引数にとります。

val names = listOf("Alice Adams", "Brian Brown", "Clara Campbell")
println(names.associate { name -> parseFullName(name).let { it.lastName to it.firstName } })  
//{Adams=Alice, Brown=Brian, Campbell=Clara}

associate()ではこのためだけにPairオブジェクトが生成されるので、パフォーマンスに影響を及ぼす可能性があります。従ってパフォーマンスがそこまで重要視されていないときや、先に説明した二つの関数が使えない場合にのみ、associate()を使うことが推奨されています。

上記コードは少し複雑なので、より分かりやすく使っている例が以下になります。

val list = listOf("abc", "cdef")
print(list.associate { it.first() to it.length } )
//{a=3, c=4}

{キー to 値}の形で指定することができます。

問題

associateBy()、associateWith()、associate()を用いて以下の関数を実装してください。

  1. customerの名前がキー、customerが値のマップを返すnameToCustomerMap()
  2. customerがキー、customerのcityが値のマップを返すcustomerToCityMap()
  3. customerの名前がキー、customerのcityが値のマップを返すcustomerNameToCityMap()

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

問題コード:

//customerの名前がキー、customerが値のマップを返す
fun Shop.nameToCustomerMap(): Map<String, Customer> =
        TODO()

//customerがキー、customerのcityが値のマップを返す
fun Shop.customerToCityMap(): Map<Customer, City> =
        TODO()

//customerの名前がキー、customerのcityが値のマップを返す
fun Shop.customerNameToCityMap(): Map<String, City> =
        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=”非表示”]

答え

//customerの名前がキー、customerが値のマップを返す
fun Shop.nameToCustomerMap(): Map<String, Customer> =
        customers.associateBy { it.name }

//customerがキー、customerのcityが値のマップを返す
fun Shop.customerToCityMap(): Map<Customer, City> =
        customers.associateWith { it.city }

//customerの名前がキー、customerのcityが値のマップを返す
fun Shop.customerNameToCityMap(): Map<String, City> =
    	customers.associate { it.name to it.city }

[解説]

nameToCutomerMap()はキーが元のリストとなるcustomersから生成されたnameなので、associateBy()を使います。

逆にcustomerToCityMap()ではキーがcustomersの要素であるcustomerなので、associateWith()を使います。

customerNameToCityMap()ではキーも値もcustomersから生成されたものを設定したいので、associateを使います。

別解として、customers.associateBy(Customer::name)やcustomers.associateWith(Customer::city)の形にして指定することもできます。

[/expander_maker]

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

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

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

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

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

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

おすすめ書籍

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

[itemlink post_id=”1743″]

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

[itemlink post_id=”1745″]

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

【Kotlin練習問題】コレクションの集計操作(最大値・最小値・合計等を求める方法)

上の記事でも解説した通り、リストの要素の合計は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
}
[expander_maker id=”1″ more=”答え” less=”非表示”]

答え

// 引数に渡した顧客によって注文された商品の合計金額を返す
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で行っています。

[/expander_maker]

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

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

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

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

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

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

おすすめ書籍

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

[itemlink post_id=”1743″]

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

[itemlink post_id=”1745″]

コレクションの集計操作

Kotlinのコレクションには集計操作に使われる関数が用意されています。それらの関数はコレクションの中身に基づいて一つの値を返すようになっています。

関数のほとんどは有名なもので、他のプログラミング言語と同じような使われ方がなされています。

最大・最小・平均・合計・要素数

リストなどのコレクションの集計操作ではよく要素の数であったり、最大値などを求めることが多いかと思われます。Kotlinでも当然それ用の関数が用意されているのでそちらの使い方を紹介します。

  1. minOrNull()とmaxOrNull():それぞれ要素の最小値と最大値を返します。空のコレクションに対してはnullを返します。
  2. average():数値のコレクションの要素の平均値を返します。
  3. sum():数値のコレクションの要素の合計の値を返します。
  4. count():コレクションの要素の数を返します。

使い方は全く難しくありません。以下のコードにそれぞれの使用例を挙げておきます。

fun main() {
    val numbers = listOf(2, 81, 40, 9)

    println("要素数: ${numbers.count()}")
    println("最大値: ${numbers.maxOrNull()}")
    println("最小値: ${numbers.minOrNull()}")
    println("平均値: ${numbers.average()}")
    println("合計値: ${numbers.sum()}")
}

//要素数: 4
//最大値: 81
//最小値: 2
//平均値: 33.0
//合計値: 132

セレクター関数とカスタムComparatorを用いて最大・最小値を取得する

上記であげた関数の他にもセレクター関数(引数に式を取る)やカスタムComparator(指定した比較方法)を用いて、その結果の最大値や最小値を返すための関数もあります。

  1. maxByOrNull()とminByOrNull():それぞれセレクター関数を取り、その結果の最大値または最小値を返します。
  2. maxWithOrNull()とminWithOrNull():Comparatorオブジェクトを取り、そのComparatorに基づいて最大値・最小値を返します。

上記の関数も全て空のコレクションに対してはnullを返します。

またmaxOf()minOf()という関数もそれぞれmaxByOrNull()minByOrNull()の代わりに使うこともできますが、空のコレクションに対してはNoSuchElementExceptionという例外を投げる点で異なります。

val numbers = listOf(8, 6, 12, 19)
val min3Remainder = numbers.minByOrNull { it % 3 }
println(min3Remainder)    //6

val strings = listOf("one", "two", "three", "four")
val longestString = strings.maxWithOrNull(compareBy { it.length })
println(longestString)    //three

上記コード中のmin3Remainderでは、それぞれの要素を3で割った結果、割り切れるもの中で一番小さい値を返すというセレクター関数です。

longestStringは名前の通り文字数が一番長い要素を返します。

問題

問題コードに一番注文をしている顧客を返す関数と、対象顧客が注文した中で一番高額な商品を返す関数を実装してください。

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

問題コード:

//一番注文をしている顧客を返す
fun Shop.getCustomerWithMaxOrders(): Customer? =
        TODO()

//注文した中で一番高額な商品を返す
fun getMostExpensiveProductBy(customer: Customer): Product? =
        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=”非表示”]

ヒント

ラムダ式の代わりにcallable references(コーラブル参照)というものを使うこともできます。これは it が異なるラムダ式や違う型の中で現れたりする際にコールチェーンの中で使用すると特に便利です。今回はgetMostExpensiveProductBy関数の中で使うことをお勧めします。

callable referencesを使うと、関数やプロパティ、コンストラクタなどに対する参照を呼び出したり関数型のインスタンスとして使うことができます。

例えば、以下のようなisOddという関数があります。

fun isOdd(x: Int) = x % 2 != 0

直接isOdd(5)などのように呼び出すことも当然できますが、他の関数に渡して関数型の値として使うことができます。そのためには :: 演算子を使います。

val numbers = listOf(1, 2, 3)
println(numbers.filter(::isOdd))
//[1, 3]

これを今回のgetMostExpensiveProductBy関数に活用して

customer.orders
    .flatMap(Order::products)
    .maxByOrNull(Product::price)

のような形で目的の値までたどり着くことができます。

[/expander_maker] [expander_maker id=”1″ more=”答え” less=”非表示”]

答え

//一番注文をしている顧客を返す
fun Shop.getCustomerWithMaxOrders(): Customer? =
    customers.maxByOrNull {it.orders.size}

//注文した中で一番高額な商品を返す
fun getMostExpensiveProductBy(customer: Customer): Product? =
    customer.orders
                .flatMap(Order::products)
                .maxByOrNull(Product::price)
[/expander_maker]

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

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

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

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

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

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

おすすめ書籍

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

[itemlink post_id=”1743″]

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

[itemlink post_id=”1745″]

predicateの種類

以下の記事で説明したように、Kotlinではコレクションから特定の条件でデータを抽出する際の条件はpredicateというラムダ式によって定義されます。

【Kotlin練習問題】コレクション:フィルタリング

predicateと組み合わせて使われる関数にはいくつかタイプがあり、filter()のように条件に合致する要素を返すフィルタリング用の関数の他に今回紹介する、要素がpredicateに合致しているかどうかをtrueかfalseで返すtest predicateとよばれるものがあります。

test predicateにはall()any()none()の三つがあります。それぞれの使い方を以下で説明していきます。

all()の使い方

all()は渡されたpredicateに全ての要素が合致していればtrueを返します。

空のコレクションでall()が呼び出された場合はtrueが返されます。

以下のコードをご覧ください。

val numbers = listOf("one", "two", "three", "four")

println(numbers.all { it.endsWith("e") }) //false

このコード中のpredicateはit.endWith(“e”)の部分ですが、関数名からも推測できるように要素が”e”で終わっているかを確認するためのものです。

numbersの中で”e”で終わっている要素は”one”と”three”だけなので、結果はfalseが返されます。

any()の使い方

 any()もall()と使い方は同じです。

any()の場合は渡されたpredicateに一つでも要素が合致していればtureが返されます。

先ほどと同じコードでall()との違いを確認してみましょう。

val numbers = listOf("one", "two", "three", "four")

println(numbers.any { it.endsWith("e") }) //true
println(numbers.all { it.endsWith("e") }) //false

any()の場合は一つでも合致していればtrueが返されるので、”one”と”three”があてはまり、trueが返されています。

none()の使い方

none()もall()、any()と使い方は全く同じです。

none()は渡されたpredicateに要素が一つも合致していなければtrueが返されます。

val numbers = listOf("one", "two", "three", "four")

println(numbers.none { it.endsWith("a") }) //true

今回は”a”で終わる要素を探すようにpredicateを指定していますが、”a”で終わる要素は一つもないのでtrueが返されます。

またany()とnone()に関してはpredicateがなくても使うことができます。

その場合、コレクションが空かどうかをチェックしてくれます。
any()はそのコレクションに一つでも要素があればtrue、空であればfalseを返します。

none()はany()と逆の挙動をします。

問題

all、anyを活用して以下の関数を実装してください。

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

問題コード:

// 全てのcustomerが引数に与えられたcity出身であればtrueを返す
fun Shop.checkAllCustomersAreFrom(city: City): Boolean =
        TODO()

// 与えられたcity出身のcustomerが一人でもいればtrueを返す
fun Shop.hasCustomerFrom(city: City): Boolean =
        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=”非表示”]

答え

// 全てのcustomerが引数に与えられたcity出身であればtrueを返す
fun Shop.checkAllCustomersAreFrom(city: City): Boolean =
        customers.all { it.city == city }

// 与えられたcity出身のcustomerが一人でもいればtrueを返す
fun Shop.hasCustomerFrom(city: City): Boolean =
        customers.any { it.city == city }

[解説]

customerについて調べたいので、allとanyが使われるのはShopクラスの中にあるcustomersに対してです。

predicateではit.cityでそれぞれの要素(customer)のcityと引数に与えれたcityが等しいかを調べています。

allもanyも渡されるpredicateはまるっきり同じです。

[/expander_maker]

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

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

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

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

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

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

おすすめ書籍

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

[itemlink post_id=”1743″]

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

[itemlink post_id=”1745″]

コレクションのフィルタリング

あるコレクションの中から特定の条件を満たす(または満たさない)要素だけを抽出する処理のことをフィルタリングと言います。

フィルタリングはコレクションの処理において最もメジャーな処理とも言えます。

Kotlinではフィルタリングする際の条件はpredicate(プレディケイト:述部の意)によって定義されます。predicateはコレクションの要素を取り、boolean値を返すラムダ関数のことです。

predicateに合致していればtrueそうでなければfalseが返されるようになっています。

標準ライブラリには一回の呼び出しでコレクションをフィルタリングできる拡張関数がいくつか用意されています。

これらの関数はもとのコレクションには変更を加えないので、そのコレクションが読み込み専用かそうでないかは問わずに利用することができます。

フィルタリングした結果を処理するには結果を変数に代入するか、フィルタリングの後でチェーンにして別の関数で処理します。

predicateでフィルタリングする

基本的なフィルタリング用の関数はfilter()です。predicateを使ってfilter()を呼び出すと、それに合致する要素を返します。

またListに対してもSetに対しても返される結果のコレクションはListです。Mapに対してはMapが返されます。

val numbers = listOf("one", "two", "three", "four")  
val longerThan3 = numbers.filter { it.length > 3 } //要素が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} //キーが"1"
で終わっており値が10よりも大きい
println(filteredMap) //{key11=11}

上記コードの numbers.filter { it.length > 3 }におけるit.length > 3や、numbersMap.filter { (key, value) -> key.endsWith(“1”) && value > 10}における(key, value) -> key.endsWith(“1”) && value > 10predicateに該当します。


it.length のitはnumbersに含まれるそれぞれの要素を意味します。

基本的なフィルタリング方法は以上になります。それでは確認問題を解いてみましょう。

問題

filter()を用いて指定されたcityに住む顧客(customer)のリストを返すメソッドを実装してください。

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

問題コード:

// 指定した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
}
[expander_maker id=”1″ more=”答え” less=”非表示”]

答え

fun Shop.getCustomersFrom(city: City): List<Customer> =
        customers.filter { it.city == city }

[解説]

getCustomersFrom関数に渡されたcityとcustomersに含まれる要素のcityが合致するかを調べるpredicateを指定しています。

[/expander_maker]

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

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

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

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

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

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

おすすめ書籍

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

[itemlink post_id=”1743″]

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

[itemlink post_id=”1745″]

マップ(Map)とは

Kotlinスタンダードライブラリにはコレクションを変換するための拡張関数のセットが用意されています。これらの関数は指定された変換ルールに従って既存のコレクションから新しいコレクションを生成します。このページではその一つであるマップ(Map)について解説していきます。


マッピング変換ではあるコレクションの要素に対して使われた関数の結果から新しいコレクションが生成されます。基本的なマッピング関数はmap()です。

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]

上記コードでは it * 3の部分とidx, value -> value * idxの部分がラムダ関数で、itはnumbersに含まれるそれぞれの要素を意味します。

またidxとvalueはそれぞれインデックス番号とその値(要素)を意味しており、一つ目はインデックス番号が0,値が1なので、返される値は0 * 1(=0)になります。同様に1 * 2、2 * 3と続きます。

もし変換の結果、nullが要素に含まれる場合、map()の代わりにmapNotNull()関数を使うことで、返されるコレクションからnullを取り除くことができます。mapIndexed()に対してはmapIndexedNotNull()が使えます。

val numbers = setOf(1, 2, 3)
println(numbers.mapNotNull { if ( it == 2) null else it * 3 }) //[3, 9]
println(numbers.mapIndexedNotNull { idx, value -> if (idx == 0) null else value * idx }) //[2, 6]

mapを変換する場合、2つの方法があります。一つは値を変更せずにキーのみを変換する方法と、キーを変更せずに値のみを変換する方法です。

与えられた変換ルールをキーに適用したい場合はmapKeys()を使います。値の場合はmapValues()になります。

これらの関数は両方ともmapをマップエントリー(Mapに保持されたキーと値のペアのこと)を引数にとる変換を使っているので、キーと値の両方とも処理することができます。

val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
println(numbersMap.mapKeys { it.key.uppercase() }) //{KEY1=1, KEY2=2, KEY3=3, KEY11=11}
println(numbersMap.mapValues { it.value + it.key.length }) //{key1=5, key2=6, key3=7, key11=16}

いかがでしたか?今回はマッピング変換について簡単に解説しました。
最後に確認問題を解いてみましょう。

問題

map()を用いて全ての顧客(customer)の出身地(city)を取得する拡張関数を実装してください。

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

問題コード:

//顧客の出身地を取得する
fun Shop.getCustomerCities(): Set<City> =
        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=”非表示”]

答え

fun Shop.getCustomerCities(): Set<City> =
        customers.map {it.city}.toSet()

[解説]

mapを用いてShopに含まれるcustomers(List型)をcityのリストに変換しています。ただし、返り値はSet型にしなければいけないので、最後にtoSet()をつけてListからSetに変換するのを忘れないようにしましょう。

[/expander_maker]

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

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

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

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

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

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

おすすめ書籍

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

[itemlink post_id=”1743″]

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

[itemlink post_id=”1745″]

コレクションにおける要素の順番

コレクションの要素の順番は特定のコレクション型においては重要な側面と言えます。

例えば、要素が全く同じ2つのリストでも、要素の順番が違うと等しいものとはみなされません。

Kotlinではオブジェクトの順番はいくつかの方法で定義することができます。はじめに順番の種類を確認しておきましょう。

ナチュラルオーダー(通常順)

一つ目はナチュラルオーダー(natural order)と呼ばれるものです。
これはComparableインターフェースを継承しているクラスに対して定義されます。他の順番が指定されていないときに適用されます。

ほとんどの組み込み型はComparableインターフェースを継承しているので、最初から比較できるようになっています。

自分で定義した型にナチュラルオーダーを定義するには、その型にComparableを継承させます。そのためにはcompareTo()関数を実装しなければなりません。またcompareTo()は同じ型の別のオブジェクトを引数にとり、対象となっているオブジェクトとどちらが大きいかを示すInt値を返すようにします。

以下が実装例です。

class Version(val major: Int, val minor: Int): Comparable<Version> {
    override fun compareTo(other: Version): Int {
        if (this.major != other.major) {
            return this.major - other.major
        } else if (this.minor != other.minor) {
            return this.minor - other.minor
        } else return 0
    }
}

fun main() {    
    println(Version(1, 2) > Version(1, 3)) //false 両オブジェクトのmajorは等しいがminorは右辺のほうが大きいため
    println(Version(2, 0) > Version(1, 5)) //true 左辺のmajorが右辺よりも大きいため
}

基本的な関数であるsorted()sortedDescending()はナチュラルオーダーで昇順、または降順に並び替えられたコレクションの要素を返します。この関数はComparableを継承している要素のコレクションに適用できます。

val numbers = listOf("one", "two", "three", "four")

println("Sorted ascending: ${numbers.sorted()}") //Sorted ascending: [four, one, three, two]
println("Sorted descending: ${numbers.sortedDescending()}") //Sorted descending: [two, three, one, four]

カスタムオーダー

カスタムオーダー(custom order)はどの型のインスタンスでも好きなように並び替えることができます。

Comparableを継承していないため比較出来ないオブジェクトに対してや、比較できるオブジェクトにナチュラルオーダー以外の順番を定義したりすることができます。

カスタムオーダーをある型に定義するには、Comparatorをその型に作成してあげます。
Comparatorはcompare()という関数を含んでおり、そのクラスのインスタンスを2つ、引数にとり、それらの比較結果を示すIntを返します。比較結果のIntは上のcompareTo()で示したものと同じ方式で解釈されます。

val lengthComparator = Comparator { str1: String, str2: String -> str1.length - str2.length }
println(listOf("aaa", "bb", "c").sortedWith(lengthComparator)) //[c, bb, aaa]

上はString型を辞書形式ではなく、lengthComparatorを使うことで文字の長さで比べるカスタムオーダーの例です。

Comparatorを実装するより簡単な方法はスタンダードライブラリのcompareBy()関数という使います。

compareBy()はインスタンスからComparable値を生成するラムダ関数を引数にとり、生成された値のナチュラルオーダーで並び替えるカスタムオーダーを定義します。紛らわしい言い回しになってしまいますが、もともとのインスタンスのナチュラルオーダーではありません。

compareBy()を用いると、上のコードは以下のように書き換えられます。

println(listOf("aaa", "bb", "c").sortedWith(compareBy { it.length }))

比較出来ないオブジェクトをカスタムオーダーで並び替えるには、sortedBy()またはsortedByDescending()を用います。
これらはコレクションの要素をComparable値にするためのセレクター関数をとり、その値のナチュラルオーダーで並び替えます。以下が使用例です。

val numbers = listOf("one", "two", "three", "four")

val sortedNumbers = numbers.sortedBy { it.length } //要素の長さで昇順
println("Sorted by length ascending: $sortedNumbers") //Sorted by length ascending: [one, two, four, three]
val sortedByLast = numbers.sortedByDescending { it.last() } //最後の文字で降順
println("Sorted by the last letter descending: $sortedByLast") //Sorted by the last letter descending: [four, two, one, three]

コレクションの並び替えにカスタムオーダーを定義するには、独自のComparatorを使用することもできます

それにはComparatorにsortedWith()関数を渡します。この関数を用いて、文字列を長さで並び替えるコードを書くと以下のようになります。

val numbers = listOf("one", "two", "three", "four")
println("Sorted by length ascending: ${numbers.sortedWith(compareBy { it.length })}")
//Sorted by length ascending: [one, two, four, three]

リバースオーダー(逆順)

reversed()関数を用いることで、逆順に並び替えたコレクションを取得することができます。

val numbers = listOf("one", "two", "three", "four")
println(numbers.reversed()) //[four, three, two, one]

reversed()で返されたコレクションはもとのコレクションの要素をコピーした新しいコレクションなので、もとのコレクションを後で変更しても、すでにreversed()で取得されたコレクションには影響しません

ランダムオーダー

最後がランダムオーダーです。Kotlinにはコレクションの要素をランダムに並び替えて格納された新しいリストを返す関数、shuffled()があります。引数なし、またはRandomオブジェクトを用いて呼び出すことができます。

val numbers = listOf("one", "two", "three", "four")
println(numbers.shuffled())

以上、Kotlinのコレクションのパッケージにはナチュラル、カスタム、さらにランダムオーダーでソートする関数が用意されています。このページでは読み込み専用のコレクションに適用できるソート関数を説明しました。

最後に確認問題を解いてみましょう。

問題

顧客(Customer)の注文数(Order)で降順に並び替えて返す関数を実装してください。

実装にはsortedByDescendingを使ってください。

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

問題コード:

// 顧客の注文数を降順で並び替えた顧客のリストを返す
fun Shop.getCustomersSortedByOrders(): 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
}
[expander_maker id=”1″ more=”答え” less=”非表示”]

答え

fun Shop.getCustomersSortedByOrders(): List<Customer> =
        customers.sortedByDescending { it.orders.size }

[解説]

セレクター関数として、it.orders.sizeを取ることで顧客の注文数の数を比較しています。

考える順番としては、まずShopクラスに対して使う関数なので、Shopクラスのcustomers(List型)に対してsortedByDescendingを使い、そのcustomersの中のそれぞれのcustomerがもつorders(List型)のサイズ(ordersに含まれるorderの数=注文数)を調べています。

[/expander_maker]

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

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

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

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

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

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

おすすめ書籍

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

[itemlink post_id=”1743″]

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

[itemlink post_id=”1745″]

コレクションとは

コレクション(Collection)とはSet、List、Mapといった型のことで、複数の値を格納したり、格納した値に番号を割り振ることで任意の値を取り出したりすることができるものです。

それらはコレクションヒエラルキーというものに属しており、根幹にはCollection<T>というインターフェースがあります。このインターフェースはそのコレクションのサイズを読み込んだり、値を調べるといった読み込み専用コレクションの基本的な挙動を表すものです。

Collectionは繰り返し処理を定義しているIterable<T>インターフェースを継承しています。

またCollectionを関数のパラメーターとして設定すると以下のコードのように、異なる型のコレクションにも適用させることができます。

fun printAll(strings: Collection<String>) {
        for(s in strings) print("$s ")
        println()
    }
    
fun main() {
    val stringList = listOf("one", "two", "one")
    printAll(stringList) //ここではList型が渡されている
    
    val stringSet = setOf("one", "two", "three")
    printAll(stringSet) //ここではSet型が渡されている
}

以下ではList、Set、Map、それぞれの違いを説明していきます。

Listとは

List<T>は指定された順番で要素を格納し、それぞれに紐づいたインデックス番号を振り分けます。番号は最初の要素が0から始まり、最後の要素がlastIndexになります。lastIndexはリストの要素数から1を引いた(list.size – 1)と表すこともできます。

val numbers = listOf("one", "two", "three", "four")
println("Number of elements: ${numbers.size}")
println("Third element: ${numbers.get(2)}")
println("Fourth element: ${numbers[3]}")
println("Index of element \"two\" ${numbers.indexOf("two")}")

//出力結果
//Number of elements: 4
//Third element: three
//Fourth element: four
//Index of element "two" 1

Listの要素(nullを含む)は重複することもあります。同じリスト内に何個でも等しいオブジェクトがあったり、一つのオブジェクトが何回も使われることがあります。

リスト同士は同じサイズ(要素数が同じ)で同じ位置に同じ要素がある場合、等しいものとみなされます。

val bob = Person("Bob", 31)
val people = listOf(Person("Adam", 20), bob, bob)
val people2 = listOf(Person("Adam", 20), Person("Bob", 31), bob)
println(people == people2) //true
bob.age = 32
println(people == people2) //false

Setとは

Set<T>一意性を持つ(かぶりがない)要素を格納します。通常順番は定義されていません。null要素も同様に一意であり、一つのSetにはnullは一つしか含むことができません

Set同士はサイズが同じ(要素数が同じ)で、Setのそれぞれの要素と等しい要素がもう一方のSetに含まれていれば等しいものとみなされます。

val numbers = setOf(1, 2, 3, 4)
println("Number of elements: ${numbers.size}")
if (numbers.contains(1)) println("1 is in the set")

val numbersBackwards = setOf(4, 3, 2, 1)
println("The sets are equal: ${numbers == numbersBackwards}")

//出力結果
//Number of elements: 4
//1 is in the set
//The sets are equal: true

Mapとは

冒頭でListやSet、Mapはコレクションヒエラルキーに属していると説明しましたが、実はMap<K, V>だけはCollectionインターフェースを継承していません。しかし他の型と同様にMapもKotlinコレクション型の一つです。

Mapはキーと値(またはエンティティ)のペアを格納します。キーには一意性がありますが、異なるキーが等しい値と紐づけられていることもありえます。Mapインターフェースにはキーで値にアクセスしたり、キーや値を検索するなどといった関数が定義されています。

/val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)

println("All keys: ${numbersMap.keys}")
println("All values: ${numbersMap.values}")
if ("key2" in numbersMap) println("Value by key \"key2\": ${numbersMap["key2"]}")    
if (1 in numbersMap.values) println("The value 1 is in the map")
if (numbersMap.containsValue(1)) println("The value 1 is in the map") //上のコードと同じ意味

//出力結果
//All keys: [key1, key2, key3, key4]
//All values: [1, 2, 3, 1]
//Value by key "key2": 2
//The value 1 is in the map
//The value 1 is in the map

Map同士は等しいペアを格納をしていれば、ペアの順番に関係なく等しいものをみなされます。

val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)    
val anotherMap = mapOf("key2" to 2, "key1" to 1, "key4" to 1, "key3" to 3)

println("The maps are equal: ${numbersMap == anotherMap}") //true

問題

Kotlinスタンダードライブラリにはコレクションをより便利に活用するための拡張関数が数多く含まれています。例えば、あるコレクションを別の型のコレクションに変換するための ‘to‘から始まる関数です。(toSetやtoListなど)

拡張関数Shop.getSetOfCustomers()を実装してください。Shopクラスと全ての関連するクラスはShop.ktに含まれています。

問題コード:

fun Shop.getSetOfCustomers(): 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=”非表示”]

答え

fun Shop.getSetOfCustomers(): Set<Customer> =
        customers.toSet()
[解説]

Shopクラスに含まれているCustomersはList<Customer>型なので、Set<Customer>型に変換する必要があります。問題はじめで説明したように、Kotlinスタンダードライブラリには既にコレクション型を別のコレクション型に変換する関数が含まれているので、それを活用すれば簡単にListからSetに変換することができます。

[/expander_maker]

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

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

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

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

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

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

おすすめ書籍

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

[itemlink post_id=”1743″]

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

[itemlink post_id=”1745″]