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
puisque cette situation conduira le code à tomber dans le cas else
, ainsi qu’un tableau non -nil
mais vide.
Cependant, dans Swift, je suis tombé sur une situation dans laquelle j'ai un tableau optionnel:
var array: [Int]?
et je ne suis pas en mesure de déterminer quelle condition utiliser. J'ai quelques options, comme:
Option A: Vérifiez les cases non -nil
et les cases vides dans le même état:
if array != nil && array!.count > 0 {
println("There are objects")
} else {
println("No objects")
}
Option B: Supprime le tableau à l'aide de 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'optionB, car je répète du code dans deux conditions. Mais je ne suis pas vraiment sûr de savoir si les optionsAetCsont correctes ou si je devrais utiliser tout autre moyen de le faire.
Je sais que l'utilisation d'un tableau optionnel pourrait être évité en fonction de la situation, mais dans certains cas, il pourrait être nécessaire de demander s'il est vide. Je voudrais donc savoir comment procéder de la manière la plus simple.
Comme @vacawama l'a fait remarquer, cette méthode simple de vérification 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 uniquement quand il est nil
ou vide, puis continuer, que le tableau contienne des éléments ou non. Alors j'ai 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, lorsque array 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
, les expressions array?.count == 0
et array?.isEmpty == true
s’apparentent donc à false
.
J'essaie donc de comprendre s'il existe un moyen d'y parvenir avec une seule condition.
Swift 3 a supprimé la possibilité de comparer les options avec >
et <
, de sorte que certaines parties de la réponse précédente ne sont plus valides.
Il est toujours possible de comparer les options avec ==
. La méthode la plus simple pour vérifier si un tableau optionnel contient des valeurs est la suivante:
if array?.isEmpty == false {
print("There are objects!")
}
Il y a d'autres façons de le faire:
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 lorsque le tableau est nil
ou est vide, vous avez au moins 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")
}
Option C capture exactement la description que vous avez donnée en anglais: "Je veux faire quelque chose de spécial uniquement lorsqu'il est vide ou vide." Je vous recommanderais de l'utiliser car c'est facile à comprendre. Il n’ya rien de mal à cela, d’autant plus qu’il va "court-circuiter" et ignorer la vérification de vide si la variable est nil
.
Vous pouvez simplement faire:
if array?.count > 0 {
print("There are objects")
} else {
print("No objects")
}
Comme @Martin le fait remarquer dans les commentaires, il utilise func ><T : _Comparable>(lhs: T?, rhs: T?) -> Bool
, ce qui signifie que le compilateur encapsule 0
sous forme de Int?
afin que la comparaison puisse être faite avec le côté gauche qui est un Int?
en raison de l'appel de chaînage facultatif.
De la même manière, vous pourriez faire:
if array?.isEmpty == false {
print("There are objects")
} else {
print("No objects")
}
Remarque: vous devez explicitement comparer avec false
ici pour que cela fonctionne.
Si vous voulez faire quelque chose lorsque le tableau est nil
ou est vide, vous avez au moins 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 résume exactement la façon dont vous l'avez décrite en anglais: "Je veux faire quelque chose de spécial uniquement lorsqu'il est vide ou vide." Je vous recommanderais de l'utiliser car c'est facile à comprendre. Il n’ya rien de mal à cela, d’autant plus qu’il va "court-circuiter" et ignorer la vérification de vide si la variable est nil
.
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")
}
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épliant le tableau optionnel et si nil, substituant un tableau vide du même type. Ensuite, en prenant le résultat (non facultatif), et si isEmpty
exécute 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 l’habitude d’éviter, dans la mesure du possible, de dégainer par la force. Bien que vous soyez assuré que array
ne sera jamais nil
lorsque array!.isEmpty
sera exécuté dans ce cas particulier, il serait facile de le modifier ultérieurement et de provoquer par inadvertance un blocage. Lorsque vous vous sentez à l'aise pour forcer le dégainage des options, vous augmentez les chances que quelqu'un effectue un changement dans le futur qui compile mais se bloque au moment de l'exécution.
Non recommandé!
if array == nil || array!.isEmpty {
print("The array is nil or empty")
}
Je trouve les options qui incluent array?
(chaînage optionnel) déroutant, telles que:
Déroutant?
if !(array?.isEmpty == false) {
print("The array is nil or empty")
}
if array?.isEmpty ?? true {
print("There are no objects")
}
Option D: Si le tableau n'a pas besoin d'être optionnel, parce que vous voulez uniquement savoir 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 pourrez simplement vérifier isEmpty
.
Compatibilité Swift 3-4:
extension Optional where Wrapped: Collection {
var nilIfEmpty: Optional {
switch self {
case .some(let collection):
return collection.isEmpty ? nil : collection
default:
return nil
}
}
var isNilOrEmpty: Bool {
switch self {
case .some(let collection):
return collection.isEmpty
case .none:
return true
}
}
Usage:
guard let array = myObject?.array.nilIfEmpty else { return }
Ou
if myObject.array.isNilOrEmpty {
// Do stuff here
}
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'
Au lieu d'utiliser if
et else
, il est préférable d'utiliser simplement guard
pour rechercher un tableau vide sans créer de nouvelles variables pour le même tableau.
guard !array.isEmpty else {
return
}
// do something with non empty ‘array’
La solution intégrée élégante est la méthode map
de Optional. Cette méthode est souvent oubliée, mais elle fait exactement ce dont vous avez besoin ici; il vous permet d’envoyer un message à la chose enveloppée dans une option, en toute sécurité. Nous nous retrouvons dans ce cas avec une sorte de commutateur à trois voies: nous pouvons dire isEmpty
au tableau Optional et obtenir true, false ou nil (dans le cas où le tableau est lui-même nul).
var array : [Int]?
array.map {$0.isEmpty} // nil (because `array` is nil)
array = []
array.map {$0.isEmpty} // true (wrapped in an Optional)
array?.append(1)
array.map {$0.isEmpty} // false (wrapped in an Optional)