Give your simulator superpowers

RocketSim: An Essential Developer Tool
as recommended by Apple

CompactMap vs flatMap: The differences explained

How do you stay current as a Swift developer?

Let me do the hard work and join 19,138 developers that stay up to date using my weekly newsletter:

CompactMap and flatMap, what are the differences and when do you use each? Swift 4.1 introduced this new method with the proposal 0187: Introduce Filtermap to gain more clarity in flatMap use cases.

When to use compactMap

Use this method to receive an array of nonoptional values when your transformation produces an optional value.

See the differences between a map and a compactMap in the following example:

let scores = ["1", "2", "three", "four", "5"]

let mapped: [Int?] = scores.map { str in Int(str) }
// [1, 2, nil, nil, 5] - Two nil values as "three" and "four" are strings.

let compactMapped: [Int] = scores.compactMap { str in Int(str) }
// [1, 2, 5] - The nil values for "three" and "four" are filtered out.

When to use flatMap

Use this method to receive a single-level collection when your transformation produces a sequence or collection for each element.

See the difference between a map and a flatMap in the following example:

let scoresByName = ["Henk": [0, 5, 8], "John": [2, 5, 8]]

let mapped = scoresByName.map { $0.value }
// [[0, 5, 8], [2, 5, 8]] - An array of arrays
print(mapped)

let flatMapped = scoresByName.flatMap { $0.value }
// [0, 5, 8, 2, 5, 8] - flattened to only one array

In fact, s.flatMap(transform) is equivalent to Array(s.map(transform).joined()).

compactMap vs flatMap

The general rule of thumb here to remind yourself for when writing code:

Used on a sequence and having a transformation returning an optional value, use compactMap. If not, either map or flatMap should give you the results you need.

The reason for naming it compactMap

Although some proposed to introduce filterMap as the method name, the Swift team decided to go for compactMap instead. Reading their motivations clears things up quite a lot and explains the functionality of the method as well.

“filterMap” is a name with some precedent in other programming languages, especially functional ones, but some people felt strongly that the name was misleading because, as a combined operation, it wasn’t quite a filter or a map. Of the alternatives, the one with the strongest support seemed to be “compactMap”, which builds on the precedent of “compact”, an operation from other languages (notably Ruby) which returns a copy of the input without nil values. Swift does not currently have such an operation, and in fact it is not currently possible to express it; nonetheless, the core team agrees that it would be a reasonable operation to add, and that “compactMap” is a good name for the operation.

 
Antoine van der Lee

Written by

Antoine van der Lee

iOS Developer since 2010, former Staff iOS Engineer at WeTransfer and currently full-time Indie Developer & Founder at SwiftLee. Writing a new blog post every week related to Swift, iOS and Xcode. Regular speaker and workshop host.

Are you ready to

Turn your side projects into independence?

Learn my proven steps to transform your passion into profit.