如何使用Scala按特定顺序排列驻留在地图中的键?

时间:2017-05-28 19:30:26

标签: scala

跟进this question

如何重新排序

List(Map(d -> 4, a -> 12, c -> 30, b -> 2), Map(d -> 80, a -> 22, c -> 6666, b -> 442))

List(Map(d -> 4, b -> 2, a -> 12, c -> 30), Map(d -> 80, b -> 442, a -> 22, c -> 6666))

使用Scala?

2 个答案:

答案 0 :(得分:2)

Map通常是无序集合。更准确地说,Map是一个Set个键,其值附加了它们。由于Set只有不同的元素,并且没有排序,因此Map s。

SortedMap [String,Int]

但是,Map有一个带有排序键的实现,以及SortedMap。它使用隐式Ordering[Key]来保持按键排序的键值对(请注意,它保持键的唯一性,因此您不能为给定键提供两个值。)

例如

SortedMap(-1 -> "neg", 1 -> "pos") + (0 -> "zero") ==
  SortedMap(-1 -> "neg", 0 -> "zero", 1 -> "pos")

但是,在您的情况下,可能难以保持与通常的Ordering[String]不同(这是字典顺序)。

Seq [(String,Int)]

您可能希望将Map[String, Int]转换为Seq[(String, Int)]。这样,您可以使用值的顺序进行播放,但是您将忽略给定键的快速查找。

如果您想这样做,您可以先按顺序使用按键列表指定订单,然后使用原始地图在其上进行映射。

val original: Map[String, Int] = Map("d" -> 4, "a" -> 12, "c" -> 30, "b" -> 2)
orderedMap: List[(String, Int)] = for {
    key <- List("d", "b", "a", "c")
    value <- original.get(key)
  } yield key -> value

请注意,我使用original.get(key)来避免在原始地图中实际未定义其中一个键的情况。

现在,要使用此List[(String, Int)]类型获取给定键的值,您必须执行

def getKey(key: String): Option[Int] = orderedMap.
  find(_._1 == key).  //find the first pair where the first element is the desired key
  map(_._2)  // keep only the value if it exists.

答案 1 :(得分:0)

SortedMap.apply采用定义顺序的隐式Ordering。例如:

implicit val stringReverse = Ordering.String.reverse
val xs = Map("a" -> 3, "b" -> 5)
SortedMap(xs.toList:_*) // Map(b -> 5, a -> 3)

How to define own Ordering