A collection of Scala ‘flatMap’ examples

Scala `flatMap` FAQ: Can you share some Scala flatMap examples?
Sure. When I was first trying to learn Scala, and cram the collections' `flatMap` method into my brain, I scoured books and the internet for great `flatMap` examples. Once I had a little grasp of it I started creating my own examples, and tried to keep them simple. I share those examples in this tutorial.

Using flatMap on a list of Strings

To get started, the following examples show the differences between `map` and `flatMap` on a `Seq[String]`:
```scala> val fruits = Seq("apple", "banana", "orange")
fruits: Seq[java.lang.String] = List(apple, banana, orange)

scala> fruits.map(_.toUpperCase)
res0: Seq[java.lang.String] = List(APPLE, BANANA, ORANGE)

scala> fruits.flatMap(_.toUpperCase)
res1: Seq[Char] = List(A, P, P, L, E, B, A, N, A, N, A, O, R, A, N, G, E)
```
Quite a difference, right? Because `flatMap` treats a `String` as a sequence of `Char`, it flattens the resulting list of strings into a sequence of characters (`Seq[Char]`). I like to think of `flatMap` as a combination of `map` followed by `flatten`, so it first runs `map` on the sequence, then runs `flatten`, giving the result shown.
You can see this by running `map` and then `flatten` yourself:
```scala> val mapResult = fruits.map(_.toUpperCase)
mapResult: Seq[String] = List(APPLE, BANANA, ORANGE)

scala> val flattenResult = mapResult.flatten
flattenResult: Seq[Char] = List(A, P, P, L, E, B, A, N, A, N, A, O, R, A, N, G, E)```
Tip: I often refer to `flatMap` as `mapFlat` so I can remember how it works.

Using a list of Options with map and flatMap

The following examples show more differences between `map` and `flatMap` for a simple `String` to `Int` conversion example. Given this `toInt` method:
```def toInt(s: String): Option[Int] = {
try {
Some(Integer.parseInt(s.trim))
} catch {
// catch Exception to catch null 's'
case e: Exception => None
}
}
```
Here are a few examples to show how `map` and `flatMap` work on a simple list of strings that you want to convert to Int:
```scala> val strings = Seq("1", "2", "foo", "3", "bar")
strings: Seq[java.lang.String] = List(1, 2, foo, 3, bar)

scala> strings.map(toInt)
res0: Seq[Option[Int]] = List(Some(1), Some(2), None, Some(3), None)

scala> strings.flatMap(toInt)
res1: Seq[Int] = List(1, 2, 3)

scala> strings.flatMap(toInt).sum
res2: Int = 6
```
`flatMap` does a nice job of flattening a list that has `Some` and `None` values in it.
Once again it’s worth noting that `flatMap` is equivalent to running `map` and then `flatten`:
```scala> val mapResult = strings.map(toInt)
mapResult: Seq[Option[Int]] = List(Some(1), Some(2), None, Some(3), None)

scala> val flattenResult = mapResult.flatten
flattenResult: Seq[Int] = List(1, 2, 3)```

flatMap with another function

The following code is not mine (see the URL below), but it does a great job of demonstrating `flatMap` when given the simple method `g`, where `g` returns three `Int` values when given one `Int` as input. That is, it transforms the single `Int` to the three resulting `Int`s:
```scala> val list = List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)

scala> def g(v:Int) = List(v-1, v, v+1)
g: (v: Int)List[Int]

scala> list.map(x => g(x))
res0: List[List[Int]] = List(List(0, 1, 2), List(1, 2, 3), List(2, 3, 4), List(3, 4, 5), List(4, 5, 6))

scala> list.flatMap(x => g(x))
res1: List[Int] = List(0, 1, 2, 1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6)
```
This great example comes from the following URL:
See that page for more `map` and `flatMap` examples.

Convert Map values to a sequence with flatMap

Here's an interesting use of `flatMap` I just thought about. Although there are other ways to get the values from a Scala `map`, you can use `flatMap` for this purpose:
```scala> val map = Map(1 -> "one", 2 -> "two", 3 -> "three")
map: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> one, 2 -> two, 3 -> three)

scala> 1 to map.size flatMap(map.get)
res0: scala.collection.immutable.IndexedSeq[java.lang.String] = Vector(one, two, three)
```
By contrast, notice what the `map` method gives you:
```scala> 1 to map.size map(map.get)
res1: scala.collection.immutable.IndexedSeq[Option[java.lang.String]] = Vector(Some(one), Some(two), Some(three))
```
If you're new to Scala, note that the flatMap example is the same as this line of code, which may be more understandable:
```1 to map.size flatMap(map.get(_))
```
Again, probably not ideal, but I'm just trying to throw different ideas out here.

The folks at Twitter have put out some excellent Scala documentation, including a collection of `flatMap` examples that I've found in two different documents.
This first example invokes `flatMap` twice on a sequence of characters:
```val chars = 'a' to 'z'
val perms = chars flatMap { a =>
chars flatMap { b =>
if (a != b) Seq("%c%c".format(a, b))
else Seq()
}
}
```
Can you guess what `perms` looks like? Here is some of it:
```perms: scala.collection.immutable.IndexedSeq[String] = Vector(ab, ac, ad, ae, af, ag, ah, ai, aj ...

// goes on until ... zw, zx, zy
```
They also show the following example of `flatMap` with `Option`. Remember that an `Option` is a container of 0 or 1 things, then guess what this code does:
```val host: Option[String] = ..
val port: Option[Int] = ..

host flatMap { h =>
port map { p =>
}
}
```
Those two examples came from Twitter's Effective Scala document, which is an excellent doc.
This morning (Nov. 2, 2012), I saw the following additional flatMap examples in a new presentation by Marius:
```Seq(1,2,3,4) flatMap { x =>
Seq(x, -x)
}

// results in:
res0: Seq[Int] = List(1, -1, 2, -2, 3, -3, 4, -4)
```
Again this might be easier to understand if you look at `map` and then `flatten`:
```scala> Seq(1,2,3,4) map { x =>
|   Seq(x, -x)
| }
res1: Seq[Seq[Int]] = List(List(1, -1), List(2, -2), List(3, -3), List(4, -4))

scala> res1.flatten
res2: Seq[Int] = List(1, -1, 2, -2, 3, -3, 4, -4)
```
Here's the second example from that presentation:
```Seq(1,2,3,4) flatMap { x =>
if (x%2 == 0) Seq(x)
else Seq()
}

// results in:
res1: Seq[Int] = List(2, 4)
```

flatMap in the Play Framework

Here’s an example of `flatMap` being used in a Play Framework method:

That example comes from this page. If you look at that page, you’ll see that the other examples use `map`, but this particular example uses `flatMap`. It’s an interesting exercise to look at those examples and wonder why this is.

Scala flatmap examples - Summary

I hope it helps to show some Scala flatMap examples, without too much discussion for the moment. In the end, flatMap is just a combination of map and flatten, so if map leaves you with a list of lists (or strings), add flatten to it. If that gives you what you need, call flatMap instead of map and flatten. After a while your brain will naturally think "flat map" without needing those intermediate steps.
If you have any flatMap examples you want to share, or improvements to the code shown, just leave a note in the Comments section.
Also, here's a repeat of those earlier links: