¿Cómo convertir la lista al mapa en Kotlin?

169

Por ejemplo, tengo una lista de cadenas como:

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

y quiero convertirlo en un mapa, donde las cadenas son las claves.

Sé que debería usar la .toMap()función, pero no sé cómo, y no he visto ningún ejemplo de ella.

LordScone
fuente

Respuestas:

317

Tienes dos opciones:

La primera y más eficaz es usar la associateByfunción que toma dos lambdas para generar la clave y el valor, y alinea la creación del mapa:

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

El segundo, menos eficaz, es usar la mapfunción estándar para crear una lista de las Paircuales se puede usar toMappara generar el mapa final:

val map = friends.map { it.facebookId to it.points }.toMap()
voddan
fuente
1
gracias. ¿es más rápido porque crea un mapa y no convierte una lista de pares en un mapa, como en mi ejemplo?
LordScone
44
@lordScone Exactamente, la asignación de Pairinstancias podría ser muy costosa para grandes colecciones
voddan
41

De Lista Mapcon associatefunción

Con Kotlin 1.3, Listtiene una función llamada associate. associatetiene la siguiente declaración:

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

Devuelve un Mappar clave-valor que proporciona la transformfunción aplicada a los elementos de la colección dada.

Uso:

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 Lista Mapcon associateByfunción

Con Kotlin, Listtiene una función llamada associateBy. associateBytiene la siguiente declaración:

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

Devuelve un que Mapcontiene los valores proporcionados valueTransforme indexados por keySelectorfunciones aplicadas a elementos de la colección dada.

Uso:

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
fuente
3
¿Cuál es la diferencia entre asociado y asociado por? ¿Me gustaría preferir usar uno sobre el otro, ya que producen el mismo resultado?
waynesford
11
  • Convierta elementos de secuencia iterables en un mapa en kotlin,
  • asociado vs asociado Por vs asociado Con:

* Referencia: documentación de Kotlin

1- asociado (para establecer claves y valores): cree un mapa que pueda establecer elementos clave y de valor:

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

Si alguno de los dos pares tuviera la misma clave, el último se agregaría al mapa.

El mapa devuelto conserva el orden de iteración de entrada de la matriz original.

2- AssociateBy (solo configure Keys por cálculo): construya un mapa en el que podamos establecer nuevas Keys, se establecerán elementos análogos para los valores

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

3- AssociatedWith (solo establecer valores por cálculo): construir un mapa que podamos establecer nuevos valores, se establecerán elementos análogos para las claves

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

Ejemplo de consejos de Kotlin: ingrese la descripción de la imagen aquí

Hamed Jaliliani
fuente
10

Puede usar associatepara esta tarea:

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

En este ejemplo, las cadenas se listconvierten en las claves y sus longitudes correspondientes (como ejemplo) se convierten en los valores dentro del mapa.

s1m0nw1
fuente
7

Si tiene duplicados en su lista que no desea perder, puede hacerlo usando groupBy.

De lo contrario, como todos los demás dijeron, use associate/By/With(que en el caso de duplicados, creo, solo devolverá el último valor con esa clave).

Un ejemplo que agrupa una lista de personas por edad:

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

Resultados:

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

Eso ha cambiado en la versión RC.

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

lagos
fuente