将列表转换为映射,其中键是Scala中的索引

时间:2016-12-28 11:23:04

标签: scala list dictionary scala-collections

我有一个字符串列表

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回答。

2 个答案:

答案 0 :(得分:3)

  

我知道我可以对生成的地图进行排序

不,你不能。排序Map没有意义。但是有Map个实现以自然顺序存储密钥,例如TreeMapIntMap也是,IIRC)。请注意,与保留广告订单顺序相同,如ListMapLinkedHashMap所做的那样。

  

Scala LinkedHashMap.toMap中描述的ListMap解决方案是否保留了顺序?有效,但我不喜欢额外的括号和_ *这么简单的事情。还有其他什么东西,所以我可以直接进行链接吗?

不(至少,我不这么认为),但您可以轻松定义它:

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完全相同。

答案 1 :(得分:2)

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

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)