按值排序地图

时间:2012-04-01 16:35:39

标签: scala

我有List[(String,String)],我需要按第二个值对它们进行排序并返回一个地图

我做了以下事情:

val newMap = list.sortBy(_._2).foldLeft(Map.empty[String, String]) {
      (map, key) ⇒ map + (key._1 → key._2)
    }

列表是List[(String,String)]

但是返回的地图没有排序!!

3 个答案:

答案 0 :(得分:9)

默认Map实现是基于哈希的,并且它们不保留顺序。而是使用scala.collection.mutable.LinkedHashMap

val newMap = list.sortBy(_._2).foldLeft(new LinkedHashMap[String, String]) {
    (map, key) => map += (key._1 -> key._2)
    map
}

根据 @Rex Kerr 的建议,scala.collection.immutable.ListMap可能是目标类型的更好选择:

val newMap = list.sortBy(_._2).foldLeft(new ListMap[String, String]) {
    (map, key) => map + (key._1 -> key._2)
}

或者(再次完全归功于 @Rex Kerr ):

val newMap = new ListMap() ++ list.sortBy(_._2)

但是你真的想要实现什么?看起来您可能选择了错误的数据结构...

答案 1 :(得分:2)

我的问题假设(不是100%明确):您希望Map[A, B]根据B

排序

这是不可能的; scala有序映射是SortedMap[A, B],必须根据A类型的某些顺序对其进行排序。

根据(A, B),如果你想要的只是一对可遍历的对B,那么你就不需要Map和解决方案:

list sortBy (_._2)

......就够了。如果您希望拥有Map,那么 Tomasz 的答案看起来很诱人 - 但这会产生误导。地图未排序;它可以按已知顺序(插入顺序)遍历。这是不一样的东西 - 无论值是什么,随后对Map的添加都将出现在末尾(从遍历的角度来看)。所以我认为你需要问自己一个问题:我想做什么?

如果您关心根据第二个元素遍历一系列对,则根本不需要Map。

答案 2 :(得分:1)

这应该简单如下:

val input = List((1,1), (3,4), (20,19), (2,2))
val output = input.sortBy(_._2).toMap

输出是:

地图(1-> 1,2-> 2,3-> 4,20-> 19)