Kotlinでリストをマップに変換する方法は?


169

たとえば、次のような文字列のリストがあります。

val list = listOf("a", "b", "c", "d")

そして、文字列がキーであるマップに変換したいと思います。

この.toMap()関数を使用する必要があることはわかっていますが、その方法がわかりません。また、その例も見ていません。

回答:


316

次の2つの選択肢があります。

最初に最もパフォーマンスが高いのはassociateBy、キーと値を生成するために2つのラムダを取り、マップの作成をインライン化する関数を使用することです。

val map = friends.associateBy({it.facebookId}, {it.points})

2つ目は、パフォーマンスが低下しますが、標準map関数をPair使用しtoMapて、最終的なマップを生成するために使用できるリストを作成します。

val map = friends.map { it.facebookId to it.points }.toMap()

1
ありがとうございました。私の例のように、マップを作成し、ペアのリストをマップに変換しないため、より高速ですか?
LordScone

4
@lordScone正確に言うと、Pairインスタンスの割り当ては、大きなコレクションでは非常にコストがかかる可能性があり ます
voddan

40

からListMapassociate機能

Kotlin 1.3では、Listという関数がありますassociateassociate次の宣言があります:

fun <T, K, V> Iterable<T>.associate(transform: (T) -> Pair<K, V>): Map<K, V>

指定されたコレクションの要素に適用Mapされるtransform関数によって提供されるキーと値のペアを含むを返します。

使用法:

class Person(val name: String, val id: Int)

fun main() {
    val friends = listOf(Person("Sue Helen", 1), Person("JR", 2), Person("Pamela", 3))
    val map = friends.associate({ Pair(it.id, it.name) })
    //val map = friends.associate({ it.id to it.name }) // also works

    println(map) // prints: {1=Sue Helen, 2=JR, 3=Pamela}
}    

からListMapassociateBy機能

KotlinにListは、という関数がありますassociateByassociateBy次の宣言があります:

fun <T, K, V> Iterable<T>.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map<K, V>

指定されたコレクションの要素に適用される関数によってMap提供されvalueTransform、インデックスが付けられた値を含むを返しますkeySelector

使用法:

class Person(val name: String, val id: Int)

fun main() {
    val friends = listOf(Person("Sue Helen", 1), Person("JR", 2), Person("Pamela", 3))
    val map = friends.associateBy(keySelector = { person -> person.id }, valueTransform = { person -> person.name })
    //val map = friends.associateBy({ it.id }, { it.name }) // also works

    println(map) // prints: {1=Sue Helen, 2=JR, 3=Pamela}
}

3
AssociateとAssociateByの違いは何ですか?同じ結果が得られることを確認して、どちらか一方を使用したいですか?
Waynesford、2018年

11
  • 反復可能なシーケンス要素をkotlinのマップに変換します。
  • アソシエイトとassociateByとassociateWith:

*参照:Kotlinのドキュメント

1-関連付ける(キーと値の両方を設定する):キーと値の要素を設定できるマップを作成します。

IterableSequenceElements.associate { newKey to newValue } //Output => Map {newKey : newValue ,...}

2つのペアのいずれかに同じキーがある場合、最後のペアがマップに追加されます。

返されたマップは、元の配列のエントリ反復順序を保持します。

2-assignBy(計算によってキーを設定するだけ):新しいキーを設定できるマップを作成します。類似の要素が値に設定されます

IterableSequenceElements.associateBy { newKey } //Result: => Map {newKey : 'Values will be set  from analogous IterableSequenceElements' ,...}

3-AssociateWith(計算によって値を設定するだけ):新しい値を設定できるマップを作成します。類似の要素がキーに設定されます

IterableSequenceElements.associateWith { newValue }  //Result => Map { 'Keys will be set from analogous IterableSequenceElements' : newValue , ...}

Kotlinのヒントの例: ここに画像の説明を入力してください


9

associateこのタスクに使用できます。

val list = listOf("a", "b", "c", "d")
val m: Map<String, Int> = list.associate { it to it.length }

この例では、からの文字列listがキーになり、対応する長さが(例として)マップ内の値になります。


7

リストに重複したくない重複がある場合、これを使用してこれを行うことができますgroupBy

それ以外の場合は、他の誰もが言ったように、使用しますassociate/By/With(重複している場合は、そのキーを持つ最後の値のみを返します)。

人のリストを年齢別にグループ化する例:

class Person(val name: String, val age: Int)

fun main() {
    val people = listOf(Person("Sue Helen", 31), Person("JR", 25), Person("Pamela", 31))

    val duplicatesKept = people.groupBy { it.age }
    val duplicatesLost = people.associateBy({ it.age }, { it })

    println(duplicatesKept)
    println(duplicatesLost)
}

結果:

{31=[Person@41629346, Person@4eec7777], 25=[Person@3b07d329]}
{31=Person@4eec7777, 25=Person@3b07d329}

0

それはRCバージョンで変更されました。

使ってます val map = list.groupByTo(destinationMap, {it.facebookId}, { it -> it.point })

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.