It seems like in Swift 4.1 flatMap
is deprecated. However there is a new method in Swift 4.1 compactMap
which is doing the same thing?
With flatMap
you can transform each object in a collection, then remove any items that were nil.
Like flatMap
let array = ["1", "2", nil]
array.flatMap { $0 } // will return "1", "2"
Like compactMap
let array = ["1", "2", nil]
array.compactMap { $0 } // will return "1", "2"
compactMap
is doing the same thing.
What are the differences between these 2 methods? Why did Apple decide to rename the method?
There are three different variants of
flatMap
. The variant ofSequence.flatMap(_:)
that accepts a closure returning an Optional value has been deprecated. Other variants offlatMap(_:)
on both Sequence and Optional remain as is. The reason as explained in proposal document is because of the misuse.Deprecated
flatMap
variant functionality is exactly the same under a new methodcompactMap
.See details here.
The Swift standard library defines 3 overloads for
flatMap
function:The last overload function can be misused in two ways:
Consider following struct and array:
First Way: Additional Wrapping and Unwrapping:
If you needed to get an array of ages of persons included in
people
array you could use two functions :In this case the
map
function will do the job and there is no need to useflatMap
, because both produce the same result. Besides, there is a useless wrapping and unwrapping process inside this use case of flatMap.(The closure parameter wraps its returned value with an Optional and the implementation of flatMap unwraps the Optional value before returning it)Second Way - String conformance to Collection Protocol:
Think you need to get a list of persons' name from
people
array. You could use the following line :If you were using a swift version prior to 4.0 you would get a transformed list of
but in newer versions
String
conforms toCollection
protocol, So, your usage offlatMap()
would match the first overload function instead of the third one and would give you a flattened result of your transformed values:Conclusion: They deprecated third overload of flatMap()
Because of these misuses, swift team has decided to deprecate the third overload to flatMap function. And their solution to the case where you need to to deal with
Optional
s so far was to introduce a new function calledcompactMap()
which will give you the expected result.