Respostas:
Você tem duas opções:
O primeiro e mais associateBy
eficiente é usar a função que usa duas lambdas para gerar a chave e o valor e destaca a criação do mapa:
val map = friends.associateBy({it.facebookId}, {it.points})
O segundo, com menos desempenho, é usar a map
função padrão para criar uma lista da Pair
qual pode ser usada toMap
para gerar o mapa final:
val map = friends.map { it.facebookId to it.points }.toMap()
Pair
casos pode ser muito caro para grandes coleções
List
para Map
com associate
funçãoCom o Kotlin 1.3, List
tem uma função chamada associate
. associate
tem a seguinte declaração:
fun <T, K, V> Iterable<T>.associate(transform: (T) -> Pair<K, V>): Map<K, V>
Retorna um
Map
par de valores-chave contendo atransform
função aplicada aos elementos da coleção fornecida.
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
para Map
com associateBy
funçãoCom Kotlin, List
tem uma função chamada associateBy
. associateBy
tem a seguinte declaração:
fun <T, K, V> Iterable<T>.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map<K, V>
Retorna a
Map
contendo os valores fornecidosvalueTransform
e indexados porkeySelector
funções aplicadas aos elementos da coleção fornecida.
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}
}
* Referência: Documentação Kotlin
1- associar (para definir chaves e valores): Construa um mapa que possa definir elementos de chave e valor:
IterableSequenceElements.associate { newKey to newValue } //Output => Map {newKey : newValue ,...}
Se qualquer um dos dois pares tiver a mesma chave, o último será adicionado ao mapa.
O mapa retornado preserva a ordem de iteração de entrada da matriz original.
2- associarBy (basta definir chaves por cálculo): Construa um mapa para definir novas chaves, elementos análogos serão definidos para valores
IterableSequenceElements.associateBy { newKey } //Result: => Map {newKey : 'Values will be set from analogous IterableSequenceElements' ,...}
3- associarCom (apenas definir valores por cálculo): Construir um mapa que possamos definir novos valores, elementos análogos serão definidos para chaves
IterableSequenceElements.associateWith { newValue } //Result => Map { 'Keys will be set from analogous IterableSequenceElements' : newValue , ...}
Você pode usar associate
para esta tarefa:
val list = listOf("a", "b", "c", "d")
val m: Map<String, Int> = list.associate { it to it.length }
Neste exemplo, as seqüências de caracteres list
tornam - se as chaves e seus comprimentos correspondentes (como exemplo) tornam-se os valores dentro do mapa.
Se houver duplicatas em sua lista que não deseja perder, faça isso usandogroupBy
.
Caso contrário, como todo mundo disse, use associate/By/With
(que, no caso de duplicatas, acredito, retornará apenas o último valor com essa chave).
Um exemplo de agrupamento de uma lista de pessoas por idade:
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}