如何在Kotlin中将List转换为Map?

Lor*_*one 146 dictionary kotlin

例如,我有一个字符串列表,如:

val list = listOf("a", "b", "c", "d")
Run Code Online (Sandbox Code Playgroud)

我想将它转换为地图,其中字符串是键.

我知道我应该使用.toMap()函数,但我不知道如何,我还没有看到它的任何例子.

vod*_*dan 273

你有两个选择:

第一个也是性能最好的是使用associateBy带有两个lambda来生成键和值的函数,并内联地图的创建:

val map = friends.associateBy({it.facebookId}, {it.points})
Run Code Online (Sandbox Code Playgroud)

第二个性能较差的是使用标准map函数创建一个列表Pair,可以用来toMap生成最终的映射:

val map = friends.map { it.facebookId to it.points }.toMap()
Run Code Online (Sandbox Code Playgroud)

  • @lordScone确切地说,对于大型集合,`Pair`实例的分配可能非常昂贵 (4认同)

Ima*_*tit 34

#1.从ListMapassociate功能

使用Kotlin 1.3,List有一个叫做的函数associate.associate有以下声明:

fun <T, K, V> Iterable<T>.associate(transform: (T) -> Pair<K, V>): Map<K, V>
Run Code Online (Sandbox Code Playgroud)

返回Maptransform应用于给定集合的元素的函数提供的包含键 - 值对.

用法:

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}
}    
Run Code Online (Sandbox Code Playgroud)

#2.从ListMapassociateBy功能

有了Kotlin,List有一个叫做的功能associateBy.associateBy有以下声明:

fun <T, K, V> Iterable<T>.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map<K, V>
Run Code Online (Sandbox Code Playgroud)

返回Map包含valueTransformkeySelector应用于给定集合的元素的函数提供和索引的值的a .

用法:

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}
}
Run Code Online (Sandbox Code Playgroud)

  • associate和associateBy有什么区别?看到它们产生相同的结果,我是否愿意优先使用它们? (2认同)

cs_*_*pil 15

如果您不想丢失列表中的重复项,则可以使用groupBy.

否则,就像其他人所说的那样,使用associate/By/With(在重复的情况下,我相信只会返回带有该键的最后一个值)。

按年龄对人员列表进行分组的示例:

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)
}
Run Code Online (Sandbox Code Playgroud)

结果:

{31=[Person@41629346, Person@4eec7777], 25=[Person@3b07d329]}
{31=Person@4eec7777, 25=Person@3b07d329}
Run Code Online (Sandbox Code Playgroud)


Ham*_*ani 14

  • 在 kotlin 中将可迭代序列元素转换为 Map,
  • 关联 vs AssociateBy vs AssociateWith:

*参考:Kotlin 文档

1-关联(设置键和值):构建一个可以设置键和值元素的映射:

IterableSequenceElements.associate { newKey to newValue } //Output => Map {newKey : newValue ,...}
Run Code Online (Sandbox Code Playgroud)

如果两对中的任何一对具有相同的键,则最后一对被添加到映射中。

返回的映射保留原始数组的条目迭代顺序。

2- associateBy(只需通过计算设置Keys):构建一个我们可以设置新Keys的映射,将为值设置类似的元素

IterableSequenceElements.associateBy { newKey } //Result: => Map {newKey : 'Values will be set  from analogous IterableSequenceElements' ,...}
Run Code Online (Sandbox Code Playgroud)

3- associateWith(只需通过计算设置值):构建一个我们可以设置新值的映射,将为键设置类似的元素

IterableSequenceElements.associateWith { newValue }  //Result => Map { 'Keys will be set from analogous IterableSequenceElements' : newValue , ...}
Run Code Online (Sandbox Code Playgroud)

Kotlin 提示示例: 在此处输入图片说明


s1m*_*nw1 8

您可以使用associate此任务:

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

在此示例中,字符串from list成为键,而它们的相应长度(例如)成为映射内的值。