我已经定义了Map[Int, Map[String, Int]]
。
我知道如何使用ListMap对外部Map进行排序。例如:
实际上所有地图都是可变的。
var myMap: Map[ Int, scala.collection.mutable.Map[String, Int] ] = Map()
....
// add some items to myMap
....
var sortedMap = scala.collection.immutable.ListMap( myMap.toList.sortBy{_._1}:_* )
但是如何根据String对内部Map进行排序?
以下似乎是错误的:
myMap foreach {
case ( num, map ) ⇒
map = scala.collection.immutable.ListMap( map.toList.sortBy{_._1}:_* )
}
编译器说map: reassignment to val
,但我已将内部地图定义为mutable.Map
。我该怎么办?
答案 0 :(得分:0)
您可以使用mapValues
将函数应用于每个值,然后将相同的排序函数应用于第二个映射。
import scala.collection.immutable.ListMap
val myMap = Map[ Int, scala.collection.mutable.Map[String, Int] ] = Map()
....
// add some items to myMap
....
val outerSortedMap = ListMap(myMap.toList.sortBy{_._1}:_* )
val innerSortedMap = myMap.mapValues(innerMap =>
ListMap(innerMap.toList.sortBy{_._1}:_* )
)
对内部和外部地图进行排序
为此,您只需先对外部地图进行排序(以便按上述说明获得outerSortedMap
),然后对outerSortedMap
的内部地图进行排序。
val innerOuterSortedMap = outerSortedMap.mapValues(innerMap =>
ListMap(innerMap.toList.sortBy{_._1}:_*)
)
关于您的尝试
foreach方法具有以下签名:foreach[U](f: ((A, B)) ⇒ U): Unit
,因此它是一种副作用方法。你想要的是将函数应用于map
的所有值,然后用函数的结果替换值。这基本上是一个map
函数(是map
代表两个完全不同的东西),并且当你想要映射值时,函数mapValues
就存在了!
答案 1 :(得分:0)
您还可以考虑使用TreeMap
。这样您以后就不需要对地图进行排序了。
请注意,没有可变的TreeMap
,但这不是一个大问题(也许它甚至是故意的)。具有可变TreeMap
并没有带来相当大的好处,因为向平衡树添加元素需要 O(log n),无论我们是否认为结构是可变的或不可变的。 / p>
这也意味着使用TreeMap
具有与稍后进行其他类型的收集和排序相同的渐近复杂性。将 n 元素添加到TreeMap
将采用 n O(log n)= O(n log n),这与排序列表相同 n 元素。
另请注意,TreeMap
的构造函数具有隐式参数ordering: Ordering[A]
。通过在创建地图时明确设置它,如果要使用与默认值不同的标准进行排序,则可以插入自己的排序功能。
答案 2 :(得分:0)
如果你为自己定义一个sortMap
辅助函数,那就很干净了:
def sortMap[K: Ordering, V](m: scala.collection.Map[K, V]) =
ListMap(m.toList.sortBy { _._1 }: _*)
val doubleSortedMap = sortMap(myMap.mapValues(sortMap(_)))