将列表转换为地图,键是 Scala 中的索引

Convert list to a map with key being an index in Scala

我有一个字符串列表

val list = List("a", "b", "c", "d", "e")

并且我想要一个地图,其中的键作为列表中项目的索引。所以我做了以下事情:

def mapByIndexes(list: List[String]): Map[Int, String] = (1 to list.size).zip(list).toMap

但是,生成的地图不保留索引顺序,结果是这样的:

Map(5 -> "e", 1 -> "a", 2 -> "b", 3 -> "c", 4 -> "d") 

如何修改上面的代码,以便获得具有以下自然顺序的地图?

Map(1 -> "a", 2 -> "b", 3 -> "c", 4 -> "d", 5 -> "e") 

注意:我知道我可以只对生成的地图进行排序,但我可以避免该步骤并创建一个已经保留顺序的地图吗?

编辑:Scala LinkedHashMap.toMap preserves order? 中描述的 ListMap 解决方案有效,但我不喜欢额外的括号和 _* 如此简单的事情。没有别的东西可以让我有一个链接吗?如果没有,我会接受@pamu 的回答。

使用ListMap。在压缩而不是做 toMap 之后,只需构建保留元素顺序的 ListMap。您可以使用其伴随对象构建 ListMap。它接受元组的可变参数。

def mapByIndexes(list: List[String]): ListMap[Int, String] = ListMap((1 to list.size).zip(list): _*)

Scala REPL

scala> import scala.collection.immutable._
import scala.collection.immutable._

scala> def mapByIndexes(list: List[String]): ListMap[Int, String] = ListMap((1 to list.size).zip(list): _*)
mapByIndexes: (list: List[String])scala.collection.immutable.ListMap[Int,String]

scala> mapByIndexes(list)
res10: scala.collection.immutable.ListMap[Int,String] = Map(1 -> a, 2 -> b, 3 -> c, 4 -> d, 5 -> e)

I'm aware that I can just sort the resulting map

不,你不能。排序 Map 没有意义。但是有 Map 实现以自然顺序存储密钥,例如 TreeMap (IntMap 也是如此,IIRC)。请注意,它与保留插入顺序 不同 ListMapLinkedHashMap 一样。

Solution with ListMap described at Scala LinkedHashMap.toMap preserves order? works, but I don't like additional parentheses and _* for so simple thing. Isn't there anything else so I can just have a chaining?

没有(至少,我不这么认为),但你可以很容易地定义它:

implicit class ToListMap[A, B](x: Seq[(A, B)]) {
  def toListMap = ListMap(x: _*)
}

// somewhere where ToListMap is in scope or imported:
val list = List(1 -> 2, 3 -> 4)
list.toListMap

请注意 ListMap 基本上是一个列表(顾名思义),因此其中的查找比任何合理的映射实现都慢。

当然,你也可以用TreeMap做同样的事情。