2014-08-31 10 views
28

Supponiamo di avere una vasta gamma di optional definito:Swift: scorciatoia non imballato di gamma di optionals

var arrayOfOptionals: [String?] = ["Seems", "like", "an", nil, "of", "optionals"] 

posso forzare scartarlo in modo breve: var arrayForCrash = arrayOfOptionals.map { $0! }

Ma che farà app in crash, c'è qualche altra via breve (senza esplicitamente scartare) come posso scartare una serie di optional?

+0

@Antonio ["Se hai una domanda a cui già conosci la risposta e desideri documentare tale conoscenza in pubblico in modo che altri (incluso te stesso) possano trovarla in un secondo momento, è perfettamente giusto chiedere e rispondere alle tue propria domanda su un sito Stack Exchange. "] (http://stackoverflow.com/help/self-answer) –

+0

rimuovendo i miei commenti sopra - sono irrilevanti ora. @Hurden, mi scuso ancora – Antonio

+0

@Antonio nessun problema, compagno – ambientlight

risposta

76

Questa soluzione consente di ottenere un nuovo array con tutti i valori scartati e tutti nil filtrati.

nuova soluzione che utilizzano flatMap (richiede Swift 2.0):

let arrayOfOptionals: [String?] = ["Seems", "like", "an", nil, "of", "optionals"] 
let arrayWithNoOptionals = arrayOfOptionals.flatMap { $0 } 

vecchia soluzione:

let arrayOfOptionals: [String?] = ["Seems", "like", "an", nil, "of", "optionals"] 
let arrayWithNoOptionals = arrayOfOptionals.filter { $0 != nil }.map { $0! } 
+0

Questa è la soluzione migliore finora. Inoltre restituirà un array di '[String]' – Yariv

+0

Funziona solo con Swift 2, che ad oggi è ancora in beta. –

0

ne dite:

import Foundation 

var test: [String!] = ["this","is","a",nil,"test"] 
for string in test { 
    if string != nil { 
     print(string) 
    } 
} 

uscita è thisisatest.


Nel vostro caso d'uso [String!], se ho capito bene.

9

Poiché è un array di optionals, è possibile che alcune voci siano nil. Invece di forzare lo scostamento con !, utilizzare l'operatore a coalescenza n. in spire nil s in stringhe vuote.

let arrayOfOptionals: [String?] = ["This", "array", nil, "has", "some", "nils", nil] 

let array:[String] = arrayOfOptionals.map{ $0 ?? "" } 
// array is now ["This", "array", "", "has", "some", "nils", ""] 
+0

estraneo alla domanda. dovresti conoscere un'alternativa vuota nel tuo tipo di elemento. – gaussblurinc

1

ho preso @ risposta di Cenny e ha deciso di fare un operatore fuori di esso:

prefix operator <!> {} 

prefix func <!> <T>(array: [T?]) -> [T] { 
    return array.filter{ $0 != nil }.map{ $0! } 
} 

Lo sto usando per analizzare una matrice di oggetti JSON e filtrare quelli t cappello non riuscita:

static func parse(j: JSONArray) -> [Agency]? { 
    return <!>j.map { self.parse($0) } 
} 

Aggiornamento per Swift 2+:
Usa operatore flatMap e tornerà solo gli oggetti non-nil

3

Sebbene sia possibile utilizzare flatMap { $0 } per rimuovere Nils, è in realtà flatMap una funzione molto più potente, e ha una versione sovraccaricata che fa qualcosa di completamente diverso (es appiattire [[Int]] a [Int]). Se non stai attento, potresti accidentalmente invocare la funzione sbagliata.

Si consiglia di utilizzare un'estensione su SequenceType per rimuovere nils. Se si utilizza removeNils(), sarete in grado di fare essenzialmente i seguenti:

[1, nil, 2].removeNils() == [1, 2] 

Agisce facendo Optional conformi a un OptionalType protocollo che permette di estendere SequenceType s che contengono Optional valori.

Per ulteriori informazioni, vedere original answer I posted.