我有一个字符串列表
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回答。
答案 0 :(得分:3)
我知道我可以对生成的地图进行排序
不,你不能。排序Map
没有意义。但是有Map
个实现以自然顺序存储密钥,例如TreeMap
(IntMap
也是,IIRC)。请注意,不与保留广告订单顺序相同,如ListMap
和LinkedHashMap
所做的那样。
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)