1. 概要

この記事では、がKotlinでのアレイのサポートを理解するための全体的なアプローチを取ります。

2. 関数の取得と設定

まず、配列 String 値で初期化して、いくつかのスポーツの名前を保存しましょう。

sports = arrayOf("Soccer", "Cricket", "Rugby")

最新のプログラミング言語と同様に、Kotlinはゼロベースの配列インデックスを使用します。 さらに、Kotlinの Array.kt クラスは、 get 関数を提供します。この関数は、演算子のオーバーロードによって[]に変換されます。

public operator fun get(index: Int): T

get 関数を使用して、インデックスを使用して配列メンバーにアクセスしてみましょう。

Assertions.assertEquals("Soccer", sports.get(0))
Assertions.assertEquals("Cricket", sports.get(1));
Assertions.assertEquals("Rugby", sports.get(2));

配列の無効なインデックスにアクセスしようとすると、KotlinはIndexOutOfBoundsExceptionをスローします。

Assertions.assertThrows(IndexOutOfBoundsException::class.java) {
    sports.get(100)
}
Assertions.assertThrows(IndexOutOfBoundsException::class.java) {
    sports.get(-1)
}

次に、 set 関数を使用して、配列の値を変更してみましょう。

sports.set(0, "Football")
Assertions.assertEquals("Football", sports[0])

最後に、無効なインデックスを使用して値を変更し、IndexOutOfBoundsExceptionが表示されることを検証してみましょう。

Assertions.assertThrows(IndexOutOfBoundsException::class.java) {
    sports.set(10, "Football")
}

3. アレイトラバーサル

Kotlinは、配列をトラバースするための複数の方法をサポートしています。 このセクションでは、一般的なアレイトラバーサルパターンのほとんどについて説明します。 ただし、その前に、通常のサイコロの6つの面のそれぞれに書き込まれた値を格納する整数値の配列を定義しましょう。

val dice = arrayOf(1, 2, 3, 4, 5, 6)

まず、 for loopを使用してdice配列をトラバースしましょう。

for (faceValue in dice) {
    println(faceValue)
}

次に、配列イテレータを初期化して値を反復処理する方法を見てみましょう。

val iterator = dice.iterator()
while (iterator.hasNext()) {
    val faceValue = iterator.next()
    println(faceValue)
}

配列をループするもう1つの典型的なパターンは、forEachループを使用することです。

dice.forEach { faceValue ->
    println(faceValue)
}

最後に、 forEachIndexedパターンの使用方法を見てみましょう。は、配列内のインデックスとそのインデックスの値の両方を提供します。

dice.forEachIndexed { index, faceValue ->
    println("Value at $index position is $faceValue")
}

4. インプレース並べ替え

このセクションでは、配列の値をインプレースで並べ替える一般的な方法をいくつか学びます。

4.1. 設定

整数配列の値を生成して出力するヘルパー関数を定義して、それらを再利用して複数のシナリオを検証できるようにします。

まず、 initArray()関数を使用して、int配列を返します。

fun initArray(): Array<Int> {
    return arrayOf(3, 2, 50, 15, 10, 1)
}

次に、配列の値を出力する printArray()関数があります。

fun printArray(array: Array<Int>) {
    array.forEach { print("$it ") }
    println()
}

4.2. 逆行する

Kotlin は、アレイの部分的および完全なインプレース反転の両方をサポートします。 同じアレイで実行することにより、各シナリオを個別に扱います。

3 2 50 15 10 1

まず、numbers配列の完全な反転を見てみましょう。

numbers = initArray()
numbers.reverse()
printArray(numbers)

予想どおり、出力は配列全体が逆になっていることを示しています。

1 10 15 50 2 3

次に、インデックス 4 (包括的)と 6 (排他的)の間の配列を逆にします。

numbers = initArray()
numbers.reverse(4, 6)
printArray(numbers)

配列の最後の2つの値のみが変更され、index = 3までの値は変更されていないことがわかります。

3 2 50 15 1 10

4.3. 選別

Kotlin は、要素の自然な順序に従って、配列のインプレース安定ソートをサポートします。 ここでも、すべての並べ替えシナリオに元のnumbers配列を使用します。

3 2 50 15 10 1

まず、numbers配列をその範囲全体で並べ替えましょう。

numbers = initArray()
numbers.sort()
printArray(numbers)

予想どおり、番号は昇順で並べ替えられています。

1 2 3 10 15 50

次に、元の numbers 配列を、インデックス= 4 (両端を含む)から最後の位置まで並べ替えます。

numbers = initArray()
numbers.sort(4)
printArray(numbers)

index = 3 までの値は変更されないままですが、index = 4からの値は昇順で並べ替えられていることがわかります。

3 2 50 15 1 10

最後に、インデックス 0 (包括的)と 2 (排他的)の間で数値配列を並べ替えましょう。

numbers = initArray()
numbers.sort(0, 2)
printArray(numbers)

予想どおり、最初の2つの要素のみが所定の位置に並べ替えられます。

2 3 50 15 10 1

4.4. シャッフル

Kotlinは、Fisher-Yatesシャッフルアルゴリズムを使用して配列をシャッフルする2つのオーバーロードされた関数を提供します。

public fun <T> Array<T>.shuffle(): Unit
public fun <T> Array<T>.shuffle(random: Random): Unit

まず、引数なしの shuffle()関数を呼び出して、並べ替えられた配列値を確認しましょう。

numbers = initArray()
numbers.shuffle()
printArray(numbers)

予想どおり、値は所定の位置でシャッフルされます。

2 10 3 1 50 15

次に、シード値が2Randomのインスタンスを渡します。

numbers = initArray()
numbers.shuffle(Random(2))
printArray(numbers)

繰り返しますが、シャッフルは出力から非常に明白です。

1 3 50 15 10 2

シード値がシャッフルで重要な役割を果たすことに注意する必要があります。 同じ配列値と同じシード値を持つランダムインスタンスを指定すると、最初のシャッフル後に常に同じ順序の値が取得されます。

5. マップの作成

このセクションでは、配列値を変換してマップを作成するための美しいコードを作成するのに役立ついくつかの関数について説明します。

5.1. associate associateBy 、およびassociateWith

配列の値を変換して、マップのキーと値を生成できます。 さらに、キーのセットまたは値のいずれかを示すために配列値を保持することも決定できます。 これらの複数のユースケースをサポートするために、Kotlinは関数associate()associateBy()、および asssociateWith()を提供します。

いくつかの一般的な果物の名前を格納するために配列を初期化してみましょう。

val fruits = arrayOf("Pear", "Apple", "Papaya", "Banana")

ここで、名前の長さを使用して果物の名前のマッピングを作成する場合は、associate()関数を使用できます。

println(fruits.associate { Pair(it, it.length) })
{Pear=4, Apple=5, Papaya=6, Banana=6}

ただし、配列値から直接キーを生成しているため、associateWith()関数を使用して、各キーのマップの値を生成する方法を決定することもできます。

println(fruits.associateWith { it.length })
{Pear=4, Apple=5, Papaya=6, Banana=6}

最後に、果物の名前の長さをキーとして、果物の名前を値としてマップを作成する場合は、associateBy()関数を使用できます。

println(fruits.associateBy { it.length })
{4=Pear, 5=Apple, 6=Banana}

5.2. associateTo associateByTo 、およびassociateWithTo

associate()associateBy()、またはassociateWith()を使用すると、 Kotlinは新しいマップを作成し、そのデータを入力します。 ただし、associateTo()associateByTo()、およびassociateWithTo()を使用して、既存のマップにデータを入力することもできます。これらの関数の変形。

果物の名前と名前の長さの既存のマッピングがあるとしましょう。

val nameVsLengthMap = mutableMapOf("Pomegranate" to 11, "Pea" to 3)
val lengthVsNameMap = mutableMapOf(11 to "Pomegranate", 3 to "Pea")

これで、associateWithTo()およびassociateByTo()関数を使用して、これらのマップに新しい値を入力できます。

println(fruits.associateWithTo(nameVsLengthMap, { it.length }))
println(fruits.associateByTo(lengthVsNameMap, { it.length }))
{Pomegranate=11, Pea=3, Pear=4, Apple=5, Papaya=6, Banana=6}
{11=Pomegranate, 3=Pea, 4=Pear, 5=Apple, 6=Banana}

6. 結論

この記事では、配列を操作するためにKotlinでサポートされているいくつかの機能について説明しました。

いつものように、ソースコードはGitHubから入手できます。