Risposte:
Hai due scelte:
Il primo e il più performante è usare la associateBy
funzione che accetta due lambda per generare la chiave e il valore e sottolinea la creazione della mappa:
val map = friends.associateBy({it.facebookId}, {it.points})
Il secondo, meno performante, è usare la map
funzione standard per creare un elenco Pair
che può essere usato toMap
per generare la mappa finale:
val map = friends.map { it.facebookId to it.points }.toMap()
Pair
istanze potrebbero essere molto costose per le grandi collezioni
List
a Map
con associate
funzioneCon Kotlin 1.3, List
ha una funzione chiamata associate
. associate
ha la seguente dichiarazione:
fun <T, K, V> Iterable<T>.associate(transform: (T) -> Pair<K, V>): Map<K, V>
Restituisce una
Map
coppia chiave-valore contenente fornita dallatransform
funzione applicata agli elementi della raccolta specificata.
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}
}
List
a Map
con associateBy
funzioneCon Kotlin, List
ha una funzione chiamata associateBy
. associateBy
ha la seguente dichiarazione:
fun <T, K, V> Iterable<T>.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map<K, V>
Restituisce a
Map
contenente i valori fornitivalueTransform
e indicizzati dallekeySelector
funzioni applicate agli elementi della raccolta specificata.
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}
}
* Riferimento: documentazione di Kotlin
1- associa (per impostare chiavi e valori): crea una mappa in grado di impostare elementi chiave e valore:
IterableSequenceElements.associate { newKey to newValue } //Output => Map {newKey : newValue ,...}
Se una delle due coppie avesse la stessa chiave, l'ultima verrà aggiunta alla mappa.
La mappa restituita conserva l'ordine di iterazione della voce dell'array originale.
2- associateBy (basta impostare le chiavi tramite il calcolo): costruire una mappa in cui possiamo impostare nuove chiavi, elementi analoghi verranno impostati per i valori
IterableSequenceElements.associateBy { newKey } //Result: => Map {newKey : 'Values will be set from analogous IterableSequenceElements' ,...}
3- associateWith (basta impostare i valori tramite calcolo): costruire una mappa in cui possiamo impostare nuovi valori, elementi analoghi verranno impostati per le chiavi
IterableSequenceElements.associateWith { newValue } //Result => Map { 'Keys will be set from analogous IterableSequenceElements' : newValue , ...}
È possibile utilizzare associate
per questa attività:
val list = listOf("a", "b", "c", "d")
val m: Map<String, Int> = list.associate { it to it.length }
In questo esempio, le stringhe di list
diventano le chiavi e le loro lunghezze corrispondenti (come esempio) diventano i valori all'interno della mappa.
Se nel tuo elenco sono presenti duplicati che non vuoi perdere, puoi farlo utilizzandogroupBy
.
Altrimenti, come hanno detto tutti gli altri, usare associate/By/With
(che nel caso dei duplicati, credo, restituirà solo l'ultimo valore con quella chiave).
Un esempio che raggruppa un elenco di persone per età:
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)
}
risultati:
{31=[Person@41629346, Person@4eec7777], 25=[Person@3b07d329]}
{31=Person@4eec7777, 25=Person@3b07d329}