2014-06-30 35 views
6

In Objective-C, se avessi avuto la seguente proprietà:Swift: contare array opzionale

@property (strong, nonatomic) NSArray * myArray; 

Un metodo per restituire una serie di oggetti in myArray sarebbe simile:

- (NSInteger) numberOfObjectsInMyArray 
{ 
    return [self.myArray count]; 
} 

Questo sarebbe restituire il numero di oggetti nell'array o 0 se myArray == nil;

Il miglior equivalente mi viene in mente per fare questo a Swift è:

var myArray: Array<String>? 

func numberOfObjectsInMyArray() -> Int 
{ 
    return myArray ? myArray!.count : 0 
} 

Quindi controllare la matrice opzionale contiene un valore, e in tal caso scartare l'array e restituire tale valore, altrimenti restituisce 0.

È questo il modo corretto per farlo? O c'è qualcosa di più semplice?

+2

Forse restituire un 'Int? 'Opzionale? –

+0

l'opzione 'Int' non è necessaria, perché qui c'è un valore di ritorno del valore. – holex

+0

'return myArray? .count' ... sì, decisamente più corto. Ma ovviamente ciò si basa sul risultato utilizzato in un luogo in cui è consentito un optional. Non valido in 'func numberOfSectionsInTableView (tableView: UITableView!) -> Int' ad esempio –

risposta

6

Sembra il modo più semplice.

Il codice Objective-C è più breve solo perché nil è anche una forma di 0, essendo una lingua basata su C.

Poiché swift è fortemente digitato non si ha una tale stenografia. In questo caso specifico richiede un po 'più di sforzo, ma in generale si risparmia la maggior parte dei mal di testa causati dalla digitazione libera.


quanto riguarda il caso specifico, c'è un motivo per rendere la matrice facoltativo nel primo luogo? Potresti avere solo un array vuoto. Qualcosa di simile potrebbe funzionare per voi:

var myArray: Array<String> = [] 

func numberOfObjectsInMyArray() -> Int { 
    return myArray.count 
} 

(Source for this information)

+0

Mi piace! E Swift assicurerebbe che myArray abbia sempre un valore. Grazie mille. –

+0

perché un valore nullo indica un array che non è stato impostato rispetto a un array di 0 count. – altagir

3

Come sull'utilizzo optional per il valore di ritorno?

var myArray: Array<String>? 

func numberOfObjectsInMyArray() -> Int? { 
    return myArray?.count 
} 

Penso che in questo modo è più sicuro.

(Source for this information)

+0

Grazie @ King-Wizard. –

25

Provare a usare la nil coalescing operator.

Secondo la documentazione di Apple:

L'operatore coalescenza nullo (un ?? b) scarta un un optional se contiene un valore, oppure restituisce un valore predefinito b se a è pari a zero.

Quindi la funzione potrebbe essere la seguente:

func numberOfObjectsInMyArray() -> Int { 
     return (myArray?.count ?? 0) 
    } 

Sono d'accordo con gli altri che questa potrebbe essere una cattiva idea per una serie di ragioni (come fare apparire come v'è una serie con un conteggio di "0" quando in realtà non esiste un array) ma, ehi, anche le idee sbagliate richiedono un'implementazione.

EDIT:

quindi sto aggiungendo questo perché due minuti dopo che ho postato questa risposta, mi sono imbattuto in un motivo per fare esattamente quello che l'autore vuole fare.

Sto implementando il protocollo NSOutlineViewDataSource in Swift. Una delle funzioni richieste dal protocollo è:

optional func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int

Tale funzione richiede che ritorni il numero di figli del parametro item. Nel mio codice, se l'elemento ha figli, saranno archiviati in un array, var children: [Person]?

Non inizializzo quell'array finché non aggiungo effettivamente un figlio all'array.

In altre parole, al momento sto fornendo dati al NSOutlineView, children potrebbe essere nil o potrebbe essere popolato, o avrebbe potuto essere tempo popolato, ma successivamente aveva tutti gli oggetti rimossi da esso, nel qual caso non sarà nil ma è count sarà 0. NSOutlineView non si preoccupa se children è nil - tutto ciò che vuole sapere è quante righe avrà bisogno di visualizzare lo item di .

Quindi, è perfettamente logico in questa situazione restituire se children è nil. L'unica ragione per chiamare la funzione è determinare quante righe NSOutlineView avrà bisogno. Non importa se la risposta è 0 perché children è nullo o perché è vuoto.

return (children?.count ?? 0) farà quello che mi serve. Se children è nil, restituirà 0. Altrimenti restituirà count. Perfezionare!

+0

L'uso dell'operatore a coalescenza nil illustrato in questa risposta è la soluzione più pulita al problema, come indicato dall'OP (la risposta migliore).Potresti mettere in discussione le scelte dell'API, ma per il codice legacy, si tratta di un animale diverso. –

+0

Una grande risposta, grazie! Se solo potessi scegliere 2 vincitori ... –