Odpowiedzi:
Masz dwie możliwości:
Pierwszą i najbardziej wydajną metodą jest użycie associateBy
funkcji, która pobiera dwie lambdy do generowania klucza i wartości, a także wstawia do tworzenia mapy:
val map = friends.associateBy({it.facebookId}, {it.points})
Drugim, mniej wydajnym, jest użycie standardowej map
funkcji do stworzenia listy, Pair
której można użyć toMap
do wygenerowania ostatecznej mapy:
val map = friends.map { it.facebookId to it.points }.toMap()
Pair
instancji może być bardzo kosztowna w przypadku dużych kolekcji
List
do Map
zassociate
funkcjąW Kotlin 1.3 List
ma funkcję o nazwie associate
. associate
posiada następującą deklarację:
fun <T, K, V> Iterable<T>.associate(transform: (T) -> Pair<K, V>): Map<K, V>
Zwraca
Map
zawierające pary klucz-wartość dostarczone przeztransform
funkcję zastosowaną do elementów danej kolekcji.
Stosowanie:
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
do Map
zassociateBy
funkcjąU Kotlina List
ma funkcję o nazwie associateBy
. associateBy
posiada następującą deklarację:
fun <T, K, V> Iterable<T>.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map<K, V>
Zwraca wartość
Map
zawierającą wartości podane przezvalueTransform
i indeksowane przezkeySelector
funkcje zastosowane do elementów danej kolekcji.
Stosowanie:
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}
}
* Odniesienie: Dokumentacja Kotlin
1- Associate (aby ustawić zarówno klucze, jak i wartości): Zbuduj mapę, która może ustawić kluczowe i wartościowe elementy:
IterableSequenceElements.associate { newKey to newValue } //Output => Map {newKey : newValue ,...}
Jeśli którakolwiek z dwóch par ma ten sam klucz, ostatnia zostanie dodana do mapy.
Zwrócona mapa zachowuje kolejność iteracji pozycji oryginalnej tablicy.
2- AssociateBy (wystarczy ustawić klucze przez obliczenia): Zbuduj mapę, na której możemy ustawić nowe klucze, analogiczne elementy zostaną ustawione dla wartości
IterableSequenceElements.associateBy { newKey } //Result: => Map {newKey : 'Values will be set from analogous IterableSequenceElements' ,...}
3- AssociateWith (po prostu ustaw wartości przez obliczenia): Zbuduj mapę, na której możemy ustawić nowe wartości, analogiczne elementy zostaną ustawione dla kluczy
IterableSequenceElements.associateWith { newValue } //Result => Map { 'Keys will be set from analogous IterableSequenceElements' : newValue , ...}
Jeśli masz na liście duplikaty , których nie chcesz stracić, możesz to zrobić za pomocągroupBy
.
W przeciwnym razie, jak wszyscy mówili, użyj associate/By/With
(co, jak sądzę, w przypadku duplikatów zwróci tylko ostatnią wartość z tym kluczem).
Przykład grupowania listy osób według wieku:
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)
}
Wyniki:
{31=[Person@41629346, Person@4eec7777], 25=[Person@3b07d329]}
{31=Person@4eec7777, 25=Person@3b07d329}