¿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.

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

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

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í


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.


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}

0

Eso ha cambiado en la versión RC.

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.