Nirmalya - 1 year ago 73
Scala Question

# Correct interpretation of Scala Map's flatmap expression

I am scratching my head vigorously, to understand the logic that produces the value out of a flatMap() operation:

``````val ys = Map("a" -> List(1 -> 11,1 -> 111), "b" -> List(2 -> 22,2 -> 222)).flatMap(e => {
|    println("e =" + e)
|    (e._2)
| })
e =(a,List((1,11), (1,111)))
e =(b,List((2,22), (2,222)))
ys: scala.collection.immutable.Map[Int,Int] = Map(1 -> 111, 2 -> 222)
``````

The println clearly shows that flatMap is taking in one entry out of the input Map. So, e._2 is a List of Pairs. I can't figure out what exactly happens after that!

I am missing a very important and subtle step somewhere. Please enlighten me.

It can be thought of as:

First we map:

``````val a = Map("a" -> List(1 -> 11,1 -> 111), "b" -> List(2 -> 22,2 -> 222)).map(e => e._2)
// List(List((1, 11), (1, 111)), List((2, 22), (2, 222)))
``````

Then we flatten:

``````val b = a.flatten
// List((1, 11), (1, 111), (2, 22), (2, 222))
``````

Then we convert back to a map:

``````b.toMap
// Map(1 -> 111, 2 -> 222)
``````

Since a map cannot have 2 values for 1 key, the value is overwritten.

Really whats going on is that the flatMap is being converted into a loop like so:

``````for (x <- m0) b ++= f(x)
``````

where:

• m0 is our original map

• b is a collection builder that has to build a `Map`, aka, `MapBuilder`

• f is our function being passed into the flatMap (it returns a `List[(Int, Int)]`)

• x is an element in our original map

The `++=` function takes the list we got from calling `f(x)`, and calls `+=` on every element, to add it to our map. For a `Map`, `+=` just calls the original `+` operator for a `Map`, which updates the value if the key already exists.

Finally we call `result` on our builder which just returns us our `Map`.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download