2011-06-29 57 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