Swift 2.0: Understanding flatMap

Last week I wrote a blog post about a problem I was trying to solve – trying to create an array of non-optional sequenced images.

While trying to come up with the best solution, it did pop into my head to consider flatMap, but to be honest, I didn’t know much about flatMap or how to use it. A co-worker sent me a solution using double flatMap, and it didn’t look very readable or appealing.

After a great discussion in the comments and on Twitter, I learned that the solution was in fact a very simple use of flatMap:

So my goal here is to summarize the great discussion about flatMap into how I now understand it. Keep in mind that I’m learning here, so I’m definitely not the expert on it!

The Simple Use-Case

My understanding of flatMap was very basic. Here is how I initially thought of it:

Transforming Elements aka 😡

As I was writing the example above, I wanted to do something very simple – multiply each element by 2, just like I would with map. Instead I got this:

flatMap transform

No matter what I tried to do in the flatMap block, it didn’t work 😢. So I googled around, and thankfully came across a blog post I’ve seen before but should have read a lot more carefully: What do map() and flatMap() really do? by @sketchyTech. Go ahead and read it. So much useful stuff there about flatMap!

The part I’m going to point out as the biggest (and now very obvious) takeaway, is that the $0 inside of the flatMap refers to one of the arrays inside the array of arrays! Duh! So if you want to multiply the elements inside the array, you have to go one level deeper and use map:

Here is the fully written-out version with names instead of the shortcut $0 in case that makes it easier to understand:

flatMap + Optionals 😕

Since I was thinking of flatMap as dealing with nested arrays, I had a very hard time making the mental leap to understanding how it was used in my original problem:

But apparently, flatMap has magic powers when it comes to optionals:

Sure enough, when I looked at the function definition for flatMap, I found this:

In other words, flatMap is specifically overloaded to deal with Optionals. It will take an array of optionals and return an array of unwrapped optionals without any nils.

Very nice and convenient! But how does this relate to the example above of flattening nested arrays? Whey was flatMap overloaded to do this? The best explanation I’ve seen comes from this comment from Lars-Jørgen Kristiansen:

optionals flatmap

The idea of thinking of flatMap as dealing with containers vs just arrays makes things a lot clearer!

I’m sure I’m only covering the tip of the iceberg here when it comes to flatMap, but I feel like I at least have a starting point to work with here. Happy Swift 2.0!

Enjoy the article? Join over 20,000+ Swift developers and enthusiasts who get my weekly updates.