Swift documentation of flatMap reads:
Returns an array containing the non-nil results of calling the given transformation with each element of this sequence.
In the following examples when return type of ElementOfResult
is left to the compiler to infer flatMap
works as documented, yet on line 5 when ElementOfResult
is specified, thus inferred to an Optional<String>
type it seems that flatMap
stops filtering out nil
's.
Why is it doing that?
~ swift
Welcome to Apple Swift version 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1). Type :help for assistance.
1> let words = ["1989", nil, "Fearless", nil, "Red"]
words: [String?] = 5 values {
[0] = "1989"
[1] = nil
[2] = "Fearless"
[3] = nil
[4] = "Red"
}
2> words.flatMap { $0 }
$R0: [String] = 3 values {
[0] = "1989"
[1] = "Fearless"
[2] = "Red"
}
3> let resultTypeInferred = words.flatMap { $0 }
resultTypeInferred: [String] = 3 values {
[0] = "1989"
[1] = "Fearless"
[2] = "Red"
}
4> let resultTypeSpecified: [String?] = words.flatMap { $0 }
resultTypeSpecified: [String?] = 5 values {
[0] = "1989"
[1] = nil
[2] = "Fearless"
[3] = nil
[4] = "Red"
}
flatMap(_:)
returns[ElementOfResult]
, and the closure return is of typeElementOfResult?
. Therefore if you annotate the return as[String?]
, you're saying that the closure returnsString??
. Thus the optional elements are promoted to double wrapped optionals, and are all therefore.some
, so they are 'non-nil
'. Try annotating the return offlatMap(_:)
as[String]
instead, like I showed in my answer to your previous question. – Farica