2016-03-29 11 views
5

Stosuję mapę do słownika, który zawiera w sobie try. Chciałbym pominąć iterację, jeśli odwzorowany element jest nieprawidłowy.Pomiń element podczas wykonywania mapy w Swift?

Na przykład:

func doSomething<T: MyType>() -> [T] 
    dictionaries.map({ 
     try? anotherFunc($0) // Want to keep non-optionals in array, how to skip? 
    }) 
} 

W powyższej próbie, jeśli anotherFunc zwrotów nil, jak uciec bieżącej iteracji i przejść do następnego? W ten sposób nie będzie zawierać elementów, które są nil. czy to możliwe?

Odpowiedz

15

Wystarczy zastąpić map() przez 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? ... powraca nil jeśli wywołanie generuje błąd, więc te elementy zostaną pominięte w wyniku.

samowystarczalny przykład tylko do celów demonstracyjnych:

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] 

Dla Swift 3 zastąpić ErrorType przez Error.

+0

Dziękuję za umożliwienie mi odkrycia 'flatMap'! Właśnie zauważyłem, że to nie działa ze słownikami. – TruMan1

+2

@ TruMan1: Jestem pewien, że tak. Zarówno 'map' jak i' flatMap' można zastosować do słownika. Zamknięcie jest wywoływane z kluczem/wartością jako argumenty. –

+0

Masz rację, przepraszam, jeszcze raz !! – TruMan1

Powiązane problemy