Wie konvertiere ich eine Liste in eine Karte in Kotlin?

168

Zum Beispiel habe ich eine Liste von Zeichenfolgen wie:

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

und ich möchte es in eine Karte konvertieren, in der die Zeichenfolgen die Schlüssel sind.

Ich weiß, dass ich die .toMap()Funktion verwenden sollte, aber ich weiß nicht wie, und ich habe keine Beispiele dafür gesehen.

LordScone
quelle

Antworten:

315

Sie haben zwei Möglichkeiten:

Die erste und leistungsstärkste associateByFunktion besteht darin, eine Funktion zu verwenden , die zwei Lambdas zum Generieren des Schlüssels und des Werts benötigt und die Erstellung der Karte inline:

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

Die zweite, weniger leistungsfähiger ist , den Standard verwenden mapFunktion zum Erstellen einer Liste von Pairdenen verwendet werden kann , um toMapdie endgültige Karte zu erzeugen:

val map = friends.map { it.facebookId to it.points }.toMap()
Voddan
quelle
1
Danke. Ist es schneller, weil es eine Karte erstellt und keine Liste von Paaren in eine Karte konvertiert, wie in meinem Beispiel?
LordScone
4
@lordScone Genau, die Zuweisung von PairInstanzen kann für große Sammlungen sehr kostspielig sein
Voddan
40

Von Listbis Mapmit associateFunktion

Mit Kotlin 1.3 Listhat eine Funktion aufgerufen associate. associatehat die folgende Erklärung:

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

Gibt ein MapSchlüssel-Wert-Paar zurück, das von einer transformFunktion bereitgestellt wird , die auf Elemente der angegebenen Sammlung angewendet wird.

Verwendung:

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}
}    

Von Listbis Mapmit associateByFunktion

Mit Kotlin Listhat eine Funktion aufgerufen associateBy. associateByhat die folgende Erklärung:

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

Gibt a zurück, Mapdas die Werte enthält, die valueTransformvon keySelectorFunktionen bereitgestellt und indiziert werden , die auf Elemente der angegebenen Sammlung angewendet werden.

Verwendung:

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}
}
Imanou Petit
quelle
3
Was ist der Unterschied zwischen Associate und AssociateBy? Würde ich es vorziehen, eins über das andere zu verwenden, da sie das gleiche Ergebnis erzielen?
Waynesford
11
  • Konvertieren Sie iterierbare Sequenzelemente in eine Karte in Kotlin.
  • Associate vs AssociateBy vs AssociateWith:

* Referenz: Kotlin-Dokumentation

1- assoziieren (um sowohl Schlüssel als auch Werte festzulegen): Erstellen Sie eine Karte, in der Schlüssel- und Wertelemente festgelegt werden können:

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

Wenn eines von zwei Paaren denselben Schlüssel hätte, wird das letzte zur Karte hinzugefügt.

Die zurückgegebene Karte behält die Iterationsreihenfolge des ursprünglichen Arrays bei.

2- AssociateBy (nur Schlüssel durch Berechnung festlegen): Erstellen Sie eine Karte, in der wir neue Schlüssel festlegen können. Für Werte werden analoge Elemente festgelegt

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

3- AssociateWith (nur Werte durch Berechnung festlegen): Erstellen Sie eine Karte, in der wir neue Werte festlegen können. Für Schlüssel werden analoge Elemente festgelegt

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

Beispiel aus Kotlin-Tipps: Geben Sie hier die Bildbeschreibung ein

Hamed Jaliliani
quelle
9

Sie können associatefür diese Aufgabe verwenden:

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

In diesem Beispiel werden die Zeichenfolgen von listzu den Schlüsseln und ihre entsprechenden Längen (als Beispiel) zu den Werten innerhalb der Karte.

s1m0nw1
quelle
7

Wenn Ihre Liste Duplikate enthält , die Sie nicht verlieren möchten, können Sie dies mit verwendengroupBy .

Ansonsten, wie alle anderen sagten, verwenden associate/By/With (was bei Duplikaten meines Erachtens nur den letzten Wert mit diesem Schlüssel zurückgibt).

Ein Beispiel für die Gruppierung einer Liste von Personen nach Alter:

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)
}

Ergebnisse:

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

Das hat sich in der RC-Version geändert.

ich benutze val map = list.groupByTo(destinationMap, {it.facebookId}, { it -> it.point })

Lagos
quelle