A collection of Scala ‘flatMap’ examples
Scala
Sure. When I was first trying to learn Scala, and cram the collections'
You can see this by running
Once again it’s worth noting that
See that page for more
This first example invokes
This morning (Nov. 2, 2012), I saw the following additional flatMap examples in a new presentation by Marius:

That example comes from this page. If you look at that page, you’ll see that the other examples use
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:
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 betweenmap 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 toflatMapasmapFlatso I can remember how it works.
Using a list of Options with map and flatMap
The following examples show more differences betweenmap 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 demonstratingflatMap 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 Ints: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 offlatMap 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.
flatMap examples from Twitter documentation
The folks at Twitter have put out some excellent Scala documentation, including a collection offlatMap 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, zyThey 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] = ..
val addr: Option[InetSocketAddress] =
host flatMap { h =>
port map { p =>
new InetSocketAddress(h, 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 offlatMap 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:
best post.
RépondreSupprimerscala online training