2016-12-28 41 views
2

索引我有一个字符串转换列表中的地图与主要是在斯卡拉

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") 

注:我知道,我可以排序生成的地图,但我可以避开这一步,创建地图已保留订单吗?

编辑:解决方案ListMap描述在Scala LinkedHashMap.toMap preserves order?的作品,但我不喜欢额外的括号和_*这么简单的事情。没有别的,所以我可以链接?如果没有,我会接受@pamu答案。

+1

[Scala LinkedHashMap.toMap保留顺序的可能的重复?](http://stackoverflow.com/questions/6199186/scala-linkedhashmap-tomap-preserves-order) –

回答

3

我知道,我可以排序生成的地图

不,你不能。排序Map没有意义。但有自然顺序存储密钥的Map实现,如TreeMapIntMap也是,IIRC)。请注意,它是而不是与保留广告订单一样,因为ListMapLinkedHashMap这样做。

带有在Scala中描述的ListMap的解决方案LinkedHashMap.toMap保留了订单?工作,但我不喜欢附加的括号和_ *这么简单的事情。没有别的,所以我可以链接?

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

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完全一样。

+0

通过排序映射我的意思是你描述的东西。如果你谷歌的“排序地图scala”它显示这些:) –

+0

顺便说一句,你提供的代码不编译。我得到'类型不匹配;找到:Seq [(A,B)]所需:(?,?)def toListMap = ListMap(x)' –

+0

嗨Alexey - 你为什么没提到'SortedMap'?它没有解决OP对按键排序的“map”的渴望吗? –

2

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

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

斯卡拉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) 
+0

不错,也适用于我。但我不喜欢附加的括号和'_ *'。没有别的,所以我可以简单地链接? –