1

我已经定义了一个Map[Int, Map[String, Int]].

我知道如何使用 ListMap 对外部地图进行排序。例如:

实际上所有的地图都是可变的。

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. 我能做些什么?

4

3 回答 3

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}:_* )
)

对内部和外部 Map 进行排序

为此,您只需要先对外部 Map 进行排序(这样就可以得到outerSortedMap上面的解释),然后对outerSortedMap.

val innerOuterSortedMap = outerSortedMap.mapValues(innerMap =>
  ListMap(innerMap.toList.sortBy{_._1}:_*)
)

关于你的尝试

foreach 方法具有以下签名:foreach[U](f: ((A, B)) ⇒ U): Unit,因此它是一种副作用方法。您想要的是将函数应用于您的所有值,map然后用函数的结果替换这些值。这基本上是一个map函数(是的map,代表两个完全不同的东西),当你想映射值时,函数就mapValues存在了!

于 2012-10-23T09:19:20.420 回答
0

如果您sortMap为自己定义一个辅助函数,那就很干净了:

def sortMap[K: Ordering, V](m: scala.collection.Map[K, V]) = 
  ListMap(m.toList.sortBy { _._1 }: _*)

val doubleSortedMap = sortMap(myMap.mapValues(sortMap(_)))
于 2012-10-23T19:53:38.990 回答
0

您也可以考虑使用TreeMap. 这样您以后就不需要对地图进行排序了。

请注意,没有 mutable TreeMap,但这不是一个大问题(甚至可能是故意的)。拥有一个可变的TreeMap并没有带来相当大的好处,因为向平衡树添加一个元素需要O(log n),无论我们认为结构是可变的还是不可变的。

这也意味着 usingTreeMap与拥有其他类型的集合并稍后对其进行排序具有相同的渐近复杂性。将n 个元素添加到 aTreeMap将需要n O(log n) = O(n log n),这与对n 个元素的列表进行排序相同。

另请注意, 的构造函数TreeMap有一个隐式参数ordering: Ordering[A]。通过在创建地图时显式设置它,您可以插入自己的排序功能,如果您想使用一些与默认不同的标准进行排序。

于 2012-10-23T16:31:06.540 回答