flatMap vs compactMap

In Swift 4.1, the flatMap function was divided into two functions. One kept the same name:

flatMap

This method flattens a sequence.

Let’s say we have a two-dimensional array:

[sourcecode language=”javascript”]
let a = [[0,1,2],[3,4,5]]
[/sourcecode]

We can use the flatMap higher order function to ‘flatten’ this into a one-dimensional array:

[sourcecode language=”javascript”]
let b = a.flatMap{$0} //b = [0, 1, 2, 3, 4, 5]
[/sourcecode]

You could flatten a dictionary too – you would just need to specify what you want to flatten the values. Let’s say we have a dictionary of animals, divided into classes:

[sourcecode language=”javascript”]
let animals = [
“Mammals”:[“cat”, “dog”, “alpaca”],
“Reptiles”:[“lizard”, “goanna”, “snake”]
]
[/sourcecode]

You could flatten this into a one-dimensional array of all animals, ignoring class:

[sourcecode language=”javascript”]
let flatAnimals = animals.values.flatMap{$0}
flatAnimals //[“lizard”, “goanna”, “snake”, “cat”, “dog”, “alpaca”]
[/sourcecode]

compactMap

In Swift 4.1, the second function of flatMap is now called compactMap. The compactMap higher order function will remove any nil elements from a sequence. Imagine you have an array of Int optionals that contains both Ints and nil:

[sourcecode language=”javascript”]
let numbers:[Int?] = [0, nil, 1, nil, nil, 2]
[/sourcecode]

You can use the compactMap method to remove any nil values from this array:

[sourcecode language=”javascript”]
let compactNumbers = numbers.compactMap{$0}
compactNumbers //[0, 1, 2]
[/sourcecode]

You can compact a dictionary too but you’ll need to use the filter method. Here’s a dictionary with String optional values:

[sourcecode language=”javascript”]
let snakes:[String:String?] = [“A”:”Anaconda”, “B”:nil, “C”:”Cobra”]
[/sourcecode]

You can use the filter method to

[sourcecode language=”javascript”]
let compactSnakes = snakes.filter {$0.value != nil }
compactSnakes //[“A”: “Anaconda”, “C”: “Cobra”]
[/sourcecode]

You might be wondering why the compactMap function doesn’t accomodate dictionary. This will be addressed in Swift 5 with the new compactMapValues function:

[sourcecode language=”javascript”]
let compactSnakes = snakes.compactMapValues {$0}
[/sourcecode]

Here‘s the Swift evolution proposal for compactMapValues.

Unknown's avatar

iOS development with Swift - book: https://manning.com/books/ios-development-with-swift video course: https://www.manning.com/livevideo/ios-development-with-swift-lv

Tagged with: , ,
Posted in Swift

Leave a Reply

Discover more from Before I forget...

Subscribe now to keep reading and get access to the full archive.

Continue reading