2012-10-23 62 views
1

我已經定義了Map[Int, Map[String, Int]]如何在Scala中對地圖進行排序

我知道如何使用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}:_*) 

但是,如何根據字符串對內部Map進行排序呢?

下似有不妥:

myMap foreach { 
    case (num, map) ⇒ 
     map = scala.collection.immutable.ListMap(map.toList.sortBy{_._1}:_*) 
} 

編譯器說:map: reassignment to val,但我已經定義內的地圖爲mutable.Map。我能做什麼?

+0

編譯器錯誤是因爲在部分功能case語句要傳遞到'foreach'從元組聲明提取值一個'val num'和'val map'。 – tysonjh

回答

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存在!

+0

是的,我明白你的方法。謝謝。順便說一句,在排序外部地圖和內部地圖後,有沒有辦法改變我的地圖?你只需要給出一個innerSortedMap的結果,但我想在myMap上做一些改變,這樣外層和內層都會被排序。 – user1725406

+0

@ user1725406請參閱我的編輯,基本上你只需要對'outerSortedMap'的內部進行排序。 –

+0

你好,如果所有的地圖都是可變的,那麼你的方法會失敗。你知道如何對可變Map進行排序嗎?謝謝。 – user1725406

0

您也可以考慮使用TreeMap。這樣您就不需要稍後對地圖進行排序。

請注意,沒有可變的TreeMap,但這不是一個大問題(也許它甚至是故意的)。有一個可變的TreeMap沒有帶來相當大的好處,因爲向平衡樹添加一個元素需要O(log n),無論我們認爲結構是可變的還是不可變的。

這也意味着使用TreeMap具有與其他類型的後續收集和排序相同的漸近複雜性。將n元素添加到TreeMap將花費n O(log n)= 0(n log n),這與對n元素的列表進行排序相同。

另請注意,TreeMap的構造函數有一個隱含的參數ordering: Ordering[A]。通過在創建地圖時明確設置它,如果要使用與默認不同的標準進行排序,可以插入自己的排序函數。

0

這是非常乾淨的,如果你定義一個sortMap輔助函數自己:

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

val doubleSortedMap = sortMap(myMap.mapValues(sortMap(_))) 
相關問題