Kotlinでリストをマップに変換する

Kotlinでリストをマップに変換する

1. 前書き

このクイックチュートリアルでは、ListMap inKotlinに変換する方法を説明します。

2. 実装

Kotlinは便利なtoMapメソッドを提供します。これにより、複雑なオブジェクトのリストを指定すると、リスト内の要素を、指定した値でマップできます。

val user1 = User("John", 18, listOf("Hiking"))
val user2 = User("Sara", 25, listOf("Chess"))
val user3 = User("Dave", 34, listOf("Games"))

@Test
fun givenList_whenConvertToMap_thenResult() {
    val myList = listOf(user1, user2, user3)
    val myMap = myList.map { it.name to it.age }.toMap()

    assertTrue(myMap.get("John") == 18)
}

ここでは、名前と年齢のペアを作成するために“to”キーワードが使用されていることに注意してください。 このメソッドは、配列内の要素のエントリ順序を保持するマップを返す必要があります。

{John=18, Sara=25, Dave=34}

Stringの小さな配列をマップする場合も同じことが起こります。

@Test
fun givenStringList_whenConvertToMap_thenResult() {
    val myList = listOf("a", "b", "c")
    val myMap = myList.map { it to it }.toMap()

    assertTrue(myMap.get("a") == "a")
}

唯一の違いは、itの値はそれによってのみマップされるため、指定しないことです。

次に、ListMapに変換する2番目の方法として、associatedByメソッドを使用します。

@Test
fun givenList_whenAssociatedBy_thenResult() {
    val myList = listOf(user1, user2, user3)
    val myMap = myList.associateBy({ it.name }, { it.hobbies })

    assertTrue(myMap.get("John")!!.contains("Hiking"))
}

値として配列を使用するようにテストを変更しました。

{
    John=[Hiking, Swimming],
    Sara=[Chess, Board Games],
    Dave=[Games, Racing sports]
}

3. どちらを使用しますか?

両方の方法が本質的に同じ機能を達成する場合、どちらを使用する必要がありますか?

toMapは、実装の観点から、より直感的です。 ただし、この方法を使用するには、最初にArrayPairsに変換する必要があり、後でMapに変換する必要があるため、this operation will be particularly useful if we’re already operating on collections of Pairs.

他のタイプのコレクションの場合、associateAPIが最適です。

4. associate*メソッドを使用したマッピング

前の例では、associateByメソッドを使用しましたが、Kotlincollectionsパッケージには、ユースケースごとに異なるバージョンがあります。

4.1. associate()メソッド

まず、associateメソッドを使用します。このメソッドは、配列の要素に対して変換関数を使用してMapを返すだけです。

@Test
fun givenStringList_whenAssociate_thenResult() {
    val myList = listOf("a", "b", "c", "d")
    val myMap = myList.associate{ it to it }

    assertTrue(myMap.get("a") == "a")
}

4.2. associateToメソッド

このメソッドを使用して、既存のマップに要素を収集できます。

@Test
fun givenStringList_whenAssociateTo_thenResult() {
    val myList = listOf("a", "b", "c", "c", "b")
    val myMap = mutableMapOf()

    myList.associateTo(myMap) {it to it}

    assertTrue(myMap.get("a") == "a")
}

この例は不変のMap –では機能しないことを覚えておくことが重要です。

4.3. associateByToメソッド

associateByToは、入力されるマップ、keySelector関数のいずれかを渡すことができるため、3つの中で最も柔軟性があります。 指定されたキーごとに、関連付けられた値は、キーが抽出されたオブジェクトになります。

@Test
fun givenStringList_whenAssociateByToUser_thenResult() {
    val myList = listOf(user1, user2, user3, user4)
    val myMap = mutableMapOf()

    myList.associateByTo(myMap) {it.name}

    assertTrue(myMap.get("Dave")!!.age == 34)
}

または、valueTransform関数を使用できます。

@Test
fun givenStringList_whenAssociateByTo_thenResult() {
    val myList = listOf(user1, user2, user3, user4)
    val myMap = mutableMapOf()

    myList.associateByTo(myMap, {it.name}, {it.age})

    assertTrue(myMap.get("Dave") == 34)
}

if key collisions happen, only the last added value is retained.を覚えておくことが重要です

5. 結論

この記事では、KotlinでListMapに変換するさまざまな方法について説明しました。

いつものように、これらすべての例とスニペットの実装はover on GitHubにあります。 これはMavenベースのプロジェクトであるため、インポートと実行が簡単である必要があります。