将列表转换为地图,键是 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)。请注意,它与保留插入顺序 不同 ,ListMap
和 LinkedHashMap
一样。
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
做同样的事情。
我有一个字符串列表
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)。请注意,它与保留插入顺序 不同 ,ListMap
和 LinkedHashMap
一样。
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
做同样的事情。