Skip item when performing map in Swift?
Asked Answered
D

2

17

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?

Dispassion answered 29/3, 2016 at 19:26 Comment(0)
S
33

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

Separator answered 29/3, 2016 at 19:33 Comment(2)
Thank for allowing me to discover flatMap! I just noticed it doesn't work with dictionaries tho.Dispassion
@TruMan1: I am pretty sure that it does. Both map and flatMap can be applied to a dictionary. The closure is called with key/value as arguments.Separator
G
2

What I did to skip a certain index when using compactMap:

yourCollectionArray.enumerated().compactMap { index, element in
    // Skips the first 3 elements
    if index < 3 { return nil }


    // Return your transformed type here..
}
Gerah answered 23/8, 2023 at 5:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.