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


169

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

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

我想将其转换为以字符串为键的地图。

我知道我应该使用该.toMap()函数,但是我不知道如何使用该函数,也没有看到任何示例。

Answers:


316

您有两种选择:

最有效的方法是使用associateBy需要两个lambda才能生成键和值的函数,并内联地图的创建:

val map = friends.associateBy({it.facebookId}, {it.points})

第二个性能较低的方法是使用标准map函数创建一个列表,PairtoMap供生成最终地图使用:

val map = friends.map { it.facebookId to it.points }.toMap()

1
谢谢。是否更快,因为它创建了地图,而不像我的示例那样将成对列表转换为地图?
LordScone

4
@lordScone确实,Pair对于大型集合而言,实例的分配 可能会非常昂贵
voddan 2015年

40

ListMap具有associate功能

在Kotlin 1.3中,List有一个名为的功能associateassociate具有以下声明:

fun <T, K, V> Iterable<T>.associate(transform: (T) -> Pair<K, V>): Map<K, V>

返回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}
}    

ListMap具有associateBy功能

使用Kotlin,List有一个名为的功能associateByassociateBy具有以下声明:

fun <T, K, V> Iterable<T>.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map<K, V>

返回一个,Map其中包含valueTransformkeySelector应用于给定集合的元素的函数提供的值并由该函数索引。

用法:

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
associate和associateBy有什么区别?我是否希望看到它们产生相同的结果,而不是使用另一个?
Waynesford '18

11
  • 在kotlin中将可迭代序列元素转换为图,
  • associate vs associateBy vs associateWith:

*参考:Kotlin文档

1-关联(同时设置键和值):构建可以设置键和值元素的地图:

IterableSequenceElements.associate { newKey to newValue } //Output => Map {newKey : newValue ,...}

如果两对中的任何一个具有相同的密钥,则最后一个将添加到映射中。

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

2-associateBy(通过计算仅设置键):建立一个可以设置新键的映射,将为值设置类似元素

IterableSequenceElements.associateBy { newKey } //Result: => Map {newKey : 'Values will be set  from analogous IterableSequenceElements' ,...}

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

IterableSequenceElements.associateWith { newValue }  //Result => Map { 'Keys will be set from analogous IterableSequenceElements' : newValue , ...}

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


9

您可以使用associate此任务:

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

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


7

如果您不想丢失重复列表,可以使用进行操作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)
}

结果:

{31=[Person@41629346, Person@4eec7777], 25=[Person@3b07d329]}
{31=Person@4eec7777, 25=Person@3b07d329}

0

在RC版本上已更改。

我在用 val map = list.groupByTo(destinationMap, {it.facebookId}, { it -> it.point })

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.