Câu trả lời:
Bạn có hai lựa chọn:
Việc đầu tiên và hiệu quả nhất là sử dụng associateBychức năng cần hai lambdas để tạo khóa và giá trị, và nội tuyến tạo ra bản đồ:
val map = friends.associateBy({it.facebookId}, {it.points})
Thứ hai, ít hiệu suất hơn, là sử dụng mapchức năng tiêu chuẩn để tạo một danh sách Paircó thể được sử dụng toMapđể tạo bản đồ cuối cùng:
val map = friends.map { it.facebookId to it.points }.toMap()
Pairthể hiện có thể rất tốn kém cho các bộ sưu tập lớn
Listđến Mapvới associatechức năngVới Kotlin 1.3, Listcó một chức năng được gọi là associate. associatecó tuyên bố sau:
fun <T, K, V> Iterable<T>.associate(transform: (T) -> Pair<K, V>): Map<K, V>
Trả về một
Mapcặp khóa-giá trị được cung cấp bởitransformhàm được áp dụng cho các phần tử của bộ sưu tập đã cho.
Sử dụng:
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đến Mapvới associateBychức năngVới Kotlin, Listcó một chức năng được gọi là associateBy. associateBycó tuyên bố sau:
fun <T, K, V> Iterable<T>.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map<K, V>
Trả về một
Mapchứa các giá trị được cung cấp bởivalueTransformvà được lập chỉ mục bởi cáckeySelectorhàm được áp dụng cho các phần tử của bộ sưu tập đã cho.
Sử dụng:
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}
}
* Tham khảo: Tài liệu Kotlin
1- liên kết (để đặt cả Khóa & Giá trị): Xây dựng bản đồ có thể đặt các yếu tố khóa & giá trị:
IterableSequenceElements.associate { newKey to newValue } //Output => Map {newKey : newValue ,...}
Nếu bất kỳ cặp nào trong hai cặp có cùng khóa thì cái cuối cùng sẽ được thêm vào bản đồ.
Bản đồ trả về bảo tồn thứ tự lặp lại của mảng ban đầu.
2- AssociBy (chỉ cần đặt Khóa theo tính toán): Xây dựng bản đồ mà chúng ta có thể đặt Khóa mới, các yếu tố tương tự sẽ được đặt cho các giá trị
IterableSequenceElements.associateBy { newKey } //Result: => Map {newKey : 'Values will be set from analogous IterableSequenceElements' ,...}
3- AssociWith (chỉ đặt Giá trị theo tính toán): Xây dựng bản đồ mà chúng ta có thể đặt Giá trị mới, các yếu tố tương tự sẽ được đặt cho Khóa
IterableSequenceElements.associateWith { newValue } //Result => Map { 'Keys will be set from analogous IterableSequenceElements' : newValue , ...}
Nếu bạn có các bản sao trong danh sách mà bạn không muốn mất, bạn có thể thực hiện việc này bằng cách sử dụng groupBy.
Mặt khác, như mọi người khác đã nói, hãy sử dụng associate/By/With(mà trong trường hợp trùng lặp, tôi tin rằng, sẽ chỉ trả về giá trị cuối cùng với khóa đó).
Một ví dụ nhóm một danh sách những người theo độ tuổi:
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)
}
Các kết quả:
{31=[Person@41629346, Person@4eec7777], 25=[Person@3b07d329]}
{31=Person@4eec7777, 25=Person@3b07d329}