When I use flatMap
with String
type array it didn't give any warning, while it gives warning in case of Int
type array. Why? Example:
let strings = [
"I'm excited about #SwiftUI",
"#Combine looks cool too",
"This year's #WWDC was amazing"
]
strings.flatMap{$0 + "."} //No warning
let ints = [
2,3,4
]
ints.flatMap{$0 + 1} //'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value
It is because these are two different flatMap
methods.
So, before I answer your question, let’s step back and consider what flatMap
is now intended to do, namely, applying transform to a sequence and concatenating the resulting sequences. The typical example is used for “flattening” arrays of arrays):
let arrayOfArrays = [[1, 2], [3, 4, 5]]
let array = arrayOfArrays.flatMap { $0 }
print(array)
Resulting in:
[1, 2, 3, 4, 5]
The flatMap
has flattened the array of arrays to a single array.
Confusingly, there was another, now deprecated, flatMap
that would perform the transform, unwrapping optional results in a sequence or collection, but removing those that were nil
. Fortunately, that has now been renamed to compactMap
to avoid confusion. So, this is why you got your warning.
Consider:
let input: [Int?] = [0, 1, nil, 3]
let results = input.flatMap { $0 } // 'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value
print(results)
Resulting in:
[0, 1, 3]
So, we should replace flatMap
with compactMap
, as advised:
let input: [Int?] = [0, 1, nil, 3]
let results = input.compactMap { $0 }
print(results)
That will give us the desired results, without the warning.
So, let’s go back to your examples. Because strings are arrays of characters, it will take you at your word and flatten that down:
let strings = [
"I'm excited about #SwiftUI",
"#Combine looks cool too",
"This year's #WWDC was amazing"
]
let stringResults = strings.flatMap { $0 + "." }
print(stringResults)
The result of that is a flattened array of characters:
["I", "\'", "m", " ", "e", "x", "c", "i", "t", "e", "d", " ", "a", "b", "o", "u", "t", " ", "#", "S", "w", "i", "f", "t", "U", "I", ".", "#", "C", "o", "m", "b", "i", "n", "e", " ", "l", "o", "o", "k", "s", " ", "c", "o", "o", "l", " ", "t", "o", "o", ".", "T", "h", "i", "s", " ", "y", "e", "a", "r", "\'", "s", " ", "#", "W", "W", "D", "C", " ", "w", "a", "s", " ", "a", "m", "a", "z", "i", "n", "g", "."]
That obviously not what you intended, but the compiler took you at your word that you wanted to flatten the array of array of characters (i.e. the array of strings) into a flat array of characters. So that’s why there was no warning.
Needless to say, in your examples, you would use neither flatMap
(because you aren’t dealing with arrays of arrays) nor compactMap
(because you aren’t dealing with optionals). You’d just use map
:
let strings = [
"I'm excited about #SwiftUI",
"#Combine looks cool too",
"This year's #WWDC was amazing"
]
let stringsResults = strings.map { $0 + "." }
print(stringsResults)
let ints = [2, 3, 4]
let intsResults = ints.map { $0 + 1 }
print(intsResults)
Completely unrelated, but in the interest of full disclosure (but at the risk of making it even more confusing), there is actually yet another flatMap
method (!), one on the Optional
type. Admittedly, this is arguable used less commonly than the array flattening (i.e. sequence concatenating) rendition, but I should probably acknowledge its existence.
This flatMap
method on Optional
“Evaluates the given closure when this Optional
instance is not nil
, passing the unwrapped value as a parameter.” But if the optional was nil
, this flatMap
will return nil
, too.
For example:
func message(for value: Int?) -> String? {
return value.flatMap { "The value is \($0)" }
}
Thus, if value
was 42
, result would be the optional string, "The value is 42"
. But if value
was nil
, then result will be nil
.
This rendition of flatMap
is not relevant to the question at hand, but I wanted to mention it for the sake of completeness.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With