Comment convertir List to Map à Kotlin?

170

Par exemple, j'ai une liste de chaînes comme:

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

et je veux le convertir en une carte, où les chaînes sont les clés.

Je sais que je devrais utiliser la .toMap()fonction, mais je ne sais pas comment et je n'en ai vu aucun exemple.

LordScone
la source

Réponses:

319

Vous avez deux choix:

Le premier et le plus performant consiste à utiliser une associateByfonction qui prend deux lambdas pour générer la clé et la valeur, et en ligne la création de la carte:

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

La seconde, moins performante, consiste à utiliser la mapfonction standard pour créer une liste Pairdont peut être utilisée toMappour générer la carte finale:

val map = friends.map { it.facebookId to it.points }.toMap()
voddan
la source
1
Merci. est-ce plus rapide car il crée une carte et ne convertit pas une liste de paires en une carte, comme dans mon exemple?
LordScone
4
@lordScone Exactement, les allocations d' Pairinstances peuvent être très coûteuses pour les grandes collections
voddan
41

De Listà Mapavec associatefonction

Avec Kotlin 1.3, Lista une fonction appelée associate. associatea la déclaration suivante:

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

Renvoie une Mappaire clé-valeur contenant fournie par la transformfonction appliquée aux éléments de la collection donnée.

Usage:

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

De Listà Mapavec associateByfonction

Avec Kotlin, Lista une fonction appelée associateBy. associateBya la déclaration suivante:

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

Renvoie un Mapcontenant les valeurs fournies valueTransformet indexées par les keySelectorfonctions appliquées aux éléments de la collection donnée.

Usage:

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
la source
3
Quelle est la différence entre associé et associéBy? Voudrais-je préférer utiliser l'un sur l'autre, vu qu'ils produisent le même résultat?
waynesford
11
  • Convertir des éléments de séquence itérables en une carte dans kotlin,
  • Associé vs Associé Par vs Associé Avec:

* Référence: Documentation Kotlin

1- associer (pour définir à la fois les clés et les valeurs): Construisez une carte qui peut définir des éléments clé et valeur:

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

Si l'une des deux paires a la même clé, la dernière est ajoutée à la carte.

La carte retournée conserve l'ordre d'itération d'entrée du tableau d'origine.

2- associéBy (il suffit de définir les clés par calcul): Construisez une carte que nous pouvons définir de nouvelles clés, des éléments analogues seront définis pour les valeurs

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

3- associé avec (il suffit de définir les valeurs par calcul): Construisez une carte que nous pouvons définir de nouvelles valeurs, des éléments analogues seront définis pour les clés

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

Exemple de conseils Kotlin: entrez la description de l'image ici

Hamed Jaliliani
la source
10

Vous pouvez utiliser associatepour cette tâche:

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

Dans cet exemple, les chaînes de listdeviennent les clés et leurs longueurs correspondantes (à titre d'exemple) deviennent les valeurs à l'intérieur de la carte.

s1m0nw1
la source
7

Si vous avez des doublons dans votre liste que vous ne voulez pas perdre, vous pouvez le faire en utilisantgroupBy .

Sinon, comme tout le monde l'a dit, utilisez associate/By/With(qui dans le cas de doublons, je crois, ne renverra que la dernière valeur avec cette clé).

Un exemple de regroupement d'une liste de personnes par âge:

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

Résultats:

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

Cela a changé sur la version RC.

j'utilise val map = list.groupByTo(destinationMap, {it.facebookId}, { it -> it.point })

Lagos
la source