web-dev-qa-db-fra.com

Vérifier si le tableau optionnel 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 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.


MODIFIER:

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.

55
eze.scaruli

Réponse mise à jour pour Swift 3:

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.



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 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.

116
vacawama

Propriété d'extension sur le protocole 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é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")
}
6
Mobile Dan

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

5
jrturton

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
}
3
Leo

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'
3
borchero

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’
0
Phil

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)
0
matt