Vérifiez si le tableau facultatif est vide

En Objective-C, quand j'ai un tableau

NSArray *array; 

et je veux vérifier si ce n'est pas vide, je fais toujours:

 if (array.count > 0) { NSLog(@"There are objects!"); } else { NSLog(@"There are no objects..."); } 

De cette façon, il n'est pas nécessaire de vérifier si array == nil car cette situation amènera le code à tomber dans l' else cas, comme le ferait un tableau non nil mais vide.

Cependant, dans Swift, j'ai trébuché sur la situation dans laquelle j'ai un tableau optionnel:

 var array: [Int]? 

et je ne suis pas capable de déterminer quelle condition utiliser. J'ai quelques options, comme:

Option A: Vérifiez les cas non nil et vides dans le même état:

 if array != nil && array!.count > 0 { println("There are objects") } else { println("No objects") } 

Option B: dissocier le tableau en utilisant let :

 if let unbindArray = array { if (unbindArray.count > 0) { println("There are objects!") } else { println("There are no objects...") } } else { println("There are no objects...") } 

Option C: Utilisation de l'opérateur de coalescence fourni par Swift:

 if (array?.count ?? 0) > 0 { println("There are objects") } else { println("No objects") } 

Je n'aime pas beaucoup l'option B , car je répète le code dans deux conditions. Mais je ne suis pas vraiment sûr de savoir si les options A et C sont correctes ou je devrais utiliser n'importe quelle autre manière de faire ceci.

Je sais que l'utilisation d'un tableau facultatif pourrait être évitée en fonction de la situation, mais dans certains cas, il pourrait être nécessaire de requestr si elle est vide. Donc, je voudrais savoir quelle est la façon de le faire de la manière la plus simple.


MODIFIER:

Comme @vacawama l'a souligné, cette façon simple de le vérifier fonctionne:

 if array?.count > 0 { println("There are objects") } else { println("No objects") } 

Cependant, j'essayais le cas dans lequel je veux faire quelque chose de spécial seulement quand il est nil ou vide, et continue alors indépendamment de savoir si le tableau a des éléments ou non. J'ai donc essayé:

 if array?.count == 0 { println("There are no objects") } // Do something regardless whether the array has elements or not. 

Et aussi

 if array?.isEmpty == true { println("There are no objects") } // Do something regardless whether the array has elements or not. 

Mais, quand le tableau est nil , il ne tombe pas dans le corps if . Et c'est parce que, dans ce cas, array?.count == nil et array?.isEmpty == nil , de sorte que les expressions array?.count == 0 et array?.isEmpty == true toutes les deux évaluées à false .

J'essaie donc de déterminer s'il existe un moyen d'y parvenir avec une seule condition.

Réponse mise à jour pour Swift 3:

Swift 3 a supprimé la possibilité de comparer les options avec > et < , donc certaines parties de la réponse précédente ne sont plus valides.

Il est toujours possible de comparer des options avec == , donc le moyen le plus simple de vérifier si un tableau optionnel contient des valeurs est:

 if array?.isEmpty == false { print("There are objects!") } 

D'autres façons, cela peut être fait:

 if array?.count ?? 0 > 0 { print("There are objects!") } if !(array?.isEmpty ?? true) { print("There are objects!") } if array != nil && !array!.isEmpty { print("There are objects!") } if array != nil && array!.count > 0 { print("There are objects!") } if !(array ?? []).isEmpty { print("There are objects!") } if (array ?? []).count > 0 { print("There are objects!") } if let array = array, array.count > 0 { print("There are objects!") } if let array = array, !array.isEmpty { print("There are objects!") } 

Si vous voulez faire quelque chose quand le tableau est nil ou vide, vous avez au less 6 choix:

Option A:

 if !(array?.isEmpty == false) { print("There are no objects") } 

Option B:

 if array == nil || array!.count == 0 { print("There are no objects") } 

Option C:

 if array == nil || array!.isEmpty { print("There are no objects") } 

Option D:

 if (array ?? []).isEmpty { print("There are no objects") } 

Option E:

 if array?.isEmpty ?? true { print("There are no objects") } 

Option F:

 if (array?.count ?? 0) == 0 { print("There are no objects") } 

L'option C capture exactement comment vous l'avez décrit en anglais: "Je veux faire quelque chose de spécial seulement quand il est vide ou vide." Je vous recommand de l'utiliser car il est facile à comprendre. Il n'y a rien de mal à cela, d'autant plus qu'il va "court-circuiter" et sauter la case vide si la variable est nil .



Réponse précédente pour Swift 2.x:

Vous pouvez simplement faire:

 if array?.count > 0 { print("There are objects") } else { print("No objects") } 

Comme @Martin le signale dans les commentaires, il utilise func ><T : _Comparable>(lhs: T?, rhs: T?) -> Bool ce qui signifie que le compilateur renvoie 0 comme un Int? de sorte que la comparaison peut être faite avec le côté gauche qui est un Int? à cause de l'appel de chaînage optionnel.

De la même manière, vous pourriez faire:

 if array?.isEmpty == false { print("There are objects") } else { print("No objects") } 

Note: Vous devez comparer explicitement avec false ici pour que cela fonctionne.


Si vous voulez faire quelque chose quand le tableau est nil ou vide, vous avez au less 7 choix:

Option A:

 if !(array?.count > 0) { print("There are no objects") } 

Option B:

 if !(array?.isEmpty == false) { print("There are no objects") } 

Option C:

 if array == nil || array!.count == 0 { print("There are no objects") } 

Option D:

 if array == nil || array!.isEmpty { print("There are no objects") } 

Option E:

 if (array ?? []).isEmpty { print("There are no objects") } 

Option F:

 if array?.isEmpty ?? true { print("There are no objects") } 

Option G:

 if (array?.count ?? 0) == 0 { print("There are no objects") } 

L'option D capture exactement comment vous l'avez décrit en anglais: "Je veux faire quelque chose de spécial seulement quand il est vide ou vide." Je vous recommand de l'utiliser car il est facile à comprendre. Il n'y a rien de mal à cela, d'autant plus qu'il va "court-circuiter" et sauter la case vide si la variable est nil .

Option D: Si le tableau n'a pas besoin d'être optionnel, parce que vous ne vous en souciez vraiment que s'il est vide ou non, initialisez-le comme un tableau vide au lieu d'un optionnel:

 var array = [Int]() 

Maintenant, il existera toujours, et vous pouvez simplement vérifier isEmpty .

Propriété Extension sur le protocole de Collection

* Écrit dans Swift 3

 extension Optional where Wrapped: Collection { var isNilOrEmpty: Bool { switch self { case .some(let collection): return collection.isEmpty case .none: return true } } } 

Exemple d'utilisation:

 if array.isNilOrEmpty { print("The array is nil or empty") } 

Autres options

Autre que l'extension ci-dessus, je trouve l'option suivante la plus claire sans forcer le déballage des options. J'ai lu ceci comme déballant le tableau facultatif et s'il est nul, en substituant un tableau vide du même type. Ensuite, en prenant le résultat (non optionnel) de cela et si c'est le isEmpty exécutez le code conditionnel.

conseillé

 if (array ?? []).isEmpty { print("The array is nil or empty") } 

Bien que ce qui suit se lit clairement, je suggère une habitude d'éviter les options de déballage de la force autant que possible. Bien que vous soyez array!.isEmpty que ce array ne sera jamais nil quand array!.isEmpty est exécuté dans ce cas précis, il serait facile de le modifier plus tard et d'introduire par inadvertance un plantage. Lorsque vous devenez plus à l'aise, vous augmentez les chances que quelqu'un fasse un changement dans le futur qui comstack mais se bloque à l'exécution.

Non recommandé!

 if array == nil || array!.isEmpty { print("The array is nil or empty") } 

Je trouve des options qui include le array? (chaînage optionnel) déroutant comme:

Déroutant?

 if !(array?.isEmpty == false) { print("The array is nil or empty") } if array?.isEmpty ?? true { print("There are no objects") } 

Déballage conditionnel:

 if let anArray = array { if !anArray.isEmpty { //do something } } 

EDIT: Possible depuis Swift 1.2:

 if let myArray = array where !myArray.isEmpty { // do something with non empty 'myArray' } 

EDIT: Possible depuis Swift 2.0:

 guard let myArray = array where !myArray.isEmpty else { return } // do something with non empty 'myArray'