adm_
adm_

Reputation: 662

Scala set vs map in for comprehension

Playing around with Scala I'm facing these two similar pieces of code that puzzle me:

val m = Map("a"->2D, "b"->3D)

for((k, v) <- m) yield (v, k)    // Yields Map(4.0 -> a, 3.0 -> b)
for(k <- m.keys) yield (m(k), k) // Yields Set((4.0,a), (3.0,b))
  1. Why the different behavior?
  2. Is it possible to change the second comprehension so that it yields a Map instead of a Set?

I sense there is something good to learn here, any additional pointers appreciated

Upvotes: 1

Views: 84

Answers (1)

jwvh
jwvh

Reputation: 51271

Recall that a for comprehension is de-sugared into map() and flatMap() (and withFilter()) calls. In this case, because each of your examples has a single generator (<-) each one becomes a single map() call.

Also recall that map() will return the same monad (wrapper type) that it was called on.

In the 1st example you're mapping over a Map so you get a Map back: from Map[String,Double] to Map[Double,String]. The tuples are transformed in to key->value pairs.

In the 2nd example you're mapping over a Set of elements from the keys of a Map, so you get a Set back. No tuple transformation takes place. They are left as tuples.

To get a Map out of the 2nd example, i.e. to get the tuples transformed, wrap the entire for in parentheses and tag a .toMap at the end.

Upvotes: 2

Related Questions