2011-06-29 17 views
19

konstruowania scala.collection.Map z innych kolekcji, ja ciągle znajduję się pisaćScala Mapa z krotki iterable

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

Jednak to naprawdę nie działa od Map.apply zajmuje tylko zmienne argumentów - tak muszę napisać

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

dostać to, co chcę, ale to wydaje się bolesne. Czy istnieje ładniejszy sposób na utworzenie Map z krotek Iterable?

Odpowiedz

28

Należy użyć parametru TraversableOnce.toMap, który jest zdefiniowany, jeśli elementy elementu Traversalable/Iterable mają typ Tuple2. (API)

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

Albo 'foo.mapValues ​​(f) .toMap'. – missingfaktor

+0

@missingfaktor jest mapValues ​​metoda do klas innych niż Mapa? – juanchito

+0

@mayonesa, nie, ale domyślam się, że nie znałem żadnego lepszego w tym czasie! :) – missingfaktor

4

Alternatywnie można użyć jako wykorzystanie collection.breakOutCanBuildFrom niejawny argument do wywołania map; to wybierze konstruktor wyników oparty na oczekiwanym typie.

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 -> ----) 

będzie działać lepiej niż wersja .toMap, jak to tylko iteracje kolekcję raz.

To nie jest takie oczywiste, ale działa to również z myślą o zrozumieniu.

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

Dzięki za to - podczas gdy nie zamierzam używać tego w kodzie, który inni ludzie muszą czytać bez wklejenia w linkach do licznych wyjaśnień do szaleństwa "CanBuildFrom", to * jest * użyteczne dla przypadku, w którym chcę przekształcić niezmienny zakres na "mutable.Map", gdzie odpowiedź, którą zaakceptowałem wcześniej, po prostu podaje mi błąd typu. – themel

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