在scala中如何用特定的键顺序对Immutable map进行排序?

o4hqfura  于 2023-05-29  发布在  Scala
关注(0)|答案(3)|浏览(140)

我有一个不可变的map:Map(“a1”->“string1”,“a2”->“string2”,“a3”->“string3”,“a4”->“string4”)
如何按特定的键顺序排序。假设密钥按以下顺序存在:List(“a3”,“a2”,“a4”,“a1”)
所需输出:Map(“a3”->“string3”,“a2”->“string2”,“a4”->“string4”,“a1”->“string1”)
我尝试将不可变的map转换为可变的LinkedHashMap,它保留了插入顺序。但是我尝试在scala中用更简洁的方式来做这件事,我在列表中以特定的顺序存储键,我希望Map只以特定的键顺序排序。

imzjd6km

imzjd6km1#

这里有一篇很好的文章,从Alvin Alexander谈到了Scala immutable Map class: methods, examples, and syntax。Map只是一个数据结构,它有一个唯一键的集合,每个键都与一个值相关联。有不同的实现,你可以使用,他们也被列在这篇文章中解释。在这种情况下,使用SortedMap就足够了。
如果使用Map的默认实现

val map = Map(
  5 -> "5",
  2 -> "2",
  7 -> "7",
  3 -> "3",
  20 -> "20",
  12 -> "12",
  6 -> "6",
  13 -> "13",
  8 -> "8"
)
println("Map:")
map.foreach(println)

您将无法预测元素的顺序

Map:
(5,5)
(20,20)
(6,6)
(13,13)
(2,2)
(12,12)
(7,7)
(3,3)
(8,8)

如果使用SortedMap

val sortedMap = SortedMap(
  5 -> "5",
  2 -> "2",
  7 -> "7",
  3 -> "3",
  20 -> "20",
  12 -> "12",
  6 -> "6",
  13 -> "13",
  8 -> "8"
)
println("SortedMap:")
sortedMap.foreach(println)

输出将是您期望的输出

SortedMap:
(2,2)
(3,3)
(5,5)
(6,6)
(7,7)
(8,8)
(12,12)
(13,13)
(20,20)

您也可以申请自定义订单。SortedMap的文档解释了如何
一个不可变的Map,其键值对根据键上的scala.math.Ordering排序。
允许对其键执行范围查询,并且实现必须保证遍历按照Map的scala.math.Ordering排序。

g2ieeal7

g2ieeal72#

默认情况下,Map本质上是无序的数据结构。你可以使用ListMap
该类使用基于列表的数据结构实现不可变Map。列表Map迭代器和遍历方法按照键-值对第一次插入的顺序访问它们。
条目在内部以相反的插入顺序存储,这意味着最新的键位于列表的头部。因此,像head和tail这样的方法是O(n),而last和init是O(1)。其他操作,如插入或删除条目,也是O(n),这使得这个集合只适合少量元素。

import scala.collection.immutable.ListMap
val map = Map("a1"-> "string1", "a2"->"string2", "a3"->"string3", "a4"->"string4")
val order = List("a3", "a2", "a4", "a1") 
    .zipWithIndex
    .toMap 
val ordered = ListMap(map.toSeq.sortBy(t => order(t._1)):_*)
println(ordered) // ListMap(a3 -> string3, a2 -> string2, a4 -> string4, a1 -> string1)
qfe3c7zg

qfe3c7zg3#

您可以使用以下代码片段:

val m = Map("a1" -> "string1", "a2" -> "string2", "a3" -> "string3", "a4" -> "string4")
val o = List("a3", "a2", "a4", "a1")

val lm = ListMap(o.map(key => (key, m(key))): _*)
println(lm)
// ListMap(a3 -> string3, a2 -> string2, a4 -> string4, a1 -> string1)

相关问题