【问题标题】:How to convert List to Map in Kotlin?如何在 Kotlin 中将列表转换为地图?
【发布时间】:2016-01-01 08:01:45
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: dictionary kotlin


    【解决方案1】:

    如果您不想丢失列表中的重复项,您可以使用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}
    

    【讨论】:

      【解决方案2】:

      ListMapassociate 函数

      在 Kotlin 1.3 中,List 有一个名为 associate 的函数。 associate 有以下声明:

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

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

      用法:

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

      ListMapassociateBy 函数

      对于 Kotlin,List 有一个名为 associateBy 的函数。 associateBy 有以下声明:

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

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

      用法:

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

      【讨论】:

      • associate 和 associateBy 有什么区别?看到它们产生相同的结果,我是否更愿意使用其中一种?
      • 这些是我如此热爱 Kotlin 的原因。谢谢!
      【解决方案3】:
      • 在 kotlin 中将可迭代的序列元素转换为地图,
      • associate vs associateBy vs associateWith:

      *参考:Kotlin Documentation

      1- associate(设置键和值):构建可以设置键和值元素的地图:

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

      如果两对中的任何一对具有相同的键,则最后一个将添加到地图中。

      返回的map保留原数组的入口迭代顺序。

      2- associateBy(通过计算设置Keys):构建一个我们可以设置新Keys的map,为values设置类似的元素

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

      3- associateWith(通过计算设置Values):构建一个我们可以设置新Values的map,将为Keys设置类似的元素

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

      来自 Kotlin 提示的示例:

      【讨论】:

        【解决方案4】:

        您可以使用associate 执行此任务:

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

        在此示例中,来自list 的字符串成为键,它们对应的长度(作为示例)成为映射内的值。

        【讨论】:

          【解决方案5】:

          你有两个选择:

          第一个也是最高效的方法是使用associateBy 函数,该函数采用两个 lambdas 来生成键和值,并内联地图的创建:

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

          第二种,性能较差,是使用标准的map 函数来创建Pair 的列表,toMap 可以使用它来生成最终的地图:

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

          【讨论】:

          • 谢谢。是不是更快,因为它创建了一个地图,而不是像我的示例中那样将一对列表转换为地图?
          • @lordScone 没错,Pair 实例的分配对于大型集合来说可能非常昂贵
          【解决方案6】:

          这在 RC 版本上有所改变。

          我正在使用val map = list.groupByTo(destinationMap, {it.facebookId}, { it -&gt; it.point })

          【讨论】:

            猜你喜欢
            • 2022-01-01
            • 2015-06-16
            • 2016-08-24
            • 1970-01-01
            • 1970-01-01
            • 2013-05-25
            • 1970-01-01
            • 2021-06-21
            • 1970-01-01
            相关资源
            最近更新 更多