2011-06-29 178 views
19

從其他集合構建scala.collection.Map,我不斷地發現自己寫斯卡拉地圖從元組迭代

val map = Map(foo.map(x=>(x, f(x)))

不過,這並沒有真正的工作,因爲Map.apply只需要變量參數 - 所以我必須寫

val map = Map(foo.map(x=>(x, f(x)) toSeq :_*)

得到我想要的,但那似乎很痛苦。有沒有一種更漂亮的方式來構造元組的IterableMap

回答

28

使用TraversableOnce.toMap如果Traversable/Iterable的元素類型爲Tuple2,則定義它。 (API)

val map = foo.map(x=>(x, f(x)).toMap 
+1

或者'foo.mapValues(F).toMap'。 – missingfaktor

+0

@missingfaktor是mapValues類以外的方法嗎? – juanchito

+0

@mayonesa,不,但我想我當時不知道更好! :) – missingfaktor

4

或者您可以使用使用collection.breakOut爲隱含CanBuildFrom參數來調用map;這將根據預期的類型選擇一個結果生成器。

scala> val x: Map[Int, String] = (1 to 5).map(x => (x, "-" * x))(collection.breakOut) 
x: Map[Int,String] = Map(5 -> -----, 1 -> -, 2 -> --, 3 -> ---, 4 -> ----) 

它會比.toMap版本表現更好,因爲它只是迭代集合一次。

這不是很明顯,但這也適用於理解。

scala> val x: Map[Int, String] = (for (i <- (1 to 5)) yield (i, "-" * i))(collection.breakOut) 
x: Map[Int,String] = Map(5 -> -----, 1 -> -, 2 -> --, 3 -> ---, 4 -> ----) 
+0

感謝這一點 - 雖然我不打算在代碼中使用它,而其他人不必粘貼鏈接到CanBuildFrom瘋狂的大量解釋的鏈接,但它*對於我想要的情況非常有用將不可變範圍轉換爲'mutable.Map',其中我之前接受的答案只是給我一個類型錯誤。 – themel

2
val map = foo zip (foo map f) toMap