问题
I'm applying a map to a dictionary that has a try
in it. I'd like to skip the iteration if the mapped item is invalid.
For example:
func doSomething<T: MyType>() -> [T]
dictionaries.map({
try? anotherFunc($0) // Want to keep non-optionals in array, how to skip?
})
}
In the above sample, if anotherFunc
returns nil
, how to escape the current iteration and move on to the next? That way, it would not contain the items that are nil
. Is this possible?
回答1:
Just replace map()
by flatMap()
:
extension SequenceType {
/// Returns an `Array` containing the non-nil results of mapping
/// `transform` over `self`.
///
/// - Complexity: O(*M* + *N*), where *M* is the length of `self`
/// and *N* is the length of the result.
@warn_unused_result
public func flatMap<T>(@noescape transform: (Self.Generator.Element) throws -> T?) rethrows -> [T]
}
try? ...
returns nil
if the call throws an error, so those
elements will be omitted in the result.
A self-contained example just for demonstration purposes:
enum MyError : ErrorType {
case DivisionByZeroError
}
func inverse(x : Double) throws -> Double {
guard x != 0 else {
throw MyError.DivisionByZeroError
}
return 1.0/x
}
let values = [ 1.0, 2.0, 0.0, 4.0 ]
let result = values.flatMap {
try? inverse($0)
}
print(result) // [1.0, 0.5, 0.25]
For Swift 3, replace ErrorType
by Error
.
For Swift 4 use compactMap
来源:https://stackoverflow.com/questions/36293394/skip-item-when-performing-map-in-swift