23

Constructing scala.collection.Map from other collections, I constantly find myself writing:

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

However, this doesn't really work since Map.apply takes variable arguments only - so I have to write:

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

to get what I want, but that seems painful. Is there a prettier way to construct a Map from an Iterable of tuples?

3 Answers 3

34

Use TraversableOnce.toMap which is defined if the elements of a Traversable/Iterable are of type Tuple2. (API)

val map = foo.map(x=>(x, f(x)).toMap
Sign up to request clarification or add additional context in comments.

3 Comments

Or, foo.mapValues(f).toMap.
@missingfaktor is mapValues a method to classes other than Map?
@mayonesa, no, but I guess I didn't know any better at the time! :)
5

Alternatively you can use use collection.breakOut as the implicit CanBuildFrom argument to the map call; this will pick a result builder based on the expected type.

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

It will perform better than the .toMap version, as it only iterates the collection once.

It's not so obvious, but this also works with a for-comprehension.

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

1 Comment

Thanks for this - while I'm not going to use it in code that other people have to read without pasting in links to the numerous explanations to the CanBuildFrom craziness, it is useful for the case where I want to convert an immutable range to a mutable.Map, where the answer I accepted before just gives me a type error.
2
val map = foo zip (foo map f) toMap

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.