Làm cách nào để chuyển đổi Danh sách thành Bản đồ trong Kotlin?


169

Ví dụ tôi có một danh sách các chuỗi như:

val list = listOf("a", "b", "c", "d")

và tôi muốn chuyển đổi nó thành bản đồ, trong đó các chuỗi là các phím.

Tôi biết tôi nên sử dụng .toMap()chức năng này, nhưng tôi không biết làm thế nào và tôi chưa thấy bất kỳ ví dụ nào về nó.

Câu trả lời:


316

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

1
cảm ơn bạn. nó có nhanh hơn không vì nó tạo ra một bản đồ và không chuyển đổi danh sách các cặp thành bản đồ, như trong ví dụ của tôi?
LordScone

4
@lordScone Chính xác, việc phân bổ các Pairthể hiện có thể rất tốn kém cho các bộ sưu tập lớn
voddan

40

Từ Listđến Mapvới associatechức năng

Vớ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ởi transformhà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}
}    

Từ Listđến Mapvới associateBychức năng

Vớ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ởi valueTransformvà được lập chỉ mục bởi các keySelectorhà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}
}

3
Sự khác biệt giữa Associate và AssociBy là gì? Tôi có muốn sử dụng cái này hơn cái kia không, khi thấy rằng chúng tạo ra kết quả tương tự?
waynesford

11
  • Chuyển đổi các yếu tố trình tự lặp lại thành bản đồ trong kotlin,
  • kết hợp với liên kếtBy vs liên kết với:

* 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 , ...}

Ví dụ từ mẹo của Kotlin: nhập mô tả hình ảnh ở đây


9

Bạn có thể sử dụng associatecho nhiệm vụ này:

val list = listOf("a", "b", "c", "d")
val m: Map<String, Int> = list.associate { it to it.length }

Trong ví dụ này, các chuỗi từ listtrở thành các khóa và độ dài tương ứng của chúng (làm ví dụ) trở thành các giá trị bên trong bản đồ.


7

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}

0

Điều đó đã thay đổi trên phiên bản RC.

tôi đang dùng val map = list.groupByTo(destinationMap, {it.facebookId}, { it -> it.point })

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.