Vérifiez que la chaîne est nulle et vide


134

Existe-t-il un moyen de vérifier les chaînes pour nilet ""dans Swift? Dans Rails, je peux utiliser blank()pour vérifier.

J'ai actuellement ceci, mais cela semble exagéré:

    if stringA? != nil {
        if !stringA!.isEmpty {
            ...blah blah
        }
    }


1
(@sutra et @ imanou-petit) sont meilleures.
M. Ming

Réponses:


212

Si vous avez affaire à des chaînes optionnelles, cela fonctionne:

(string ?? "").isEmpty

L' ??opérateur de fusion nil renvoie le côté gauche s'il n'est pas nul, sinon il renvoie le côté droit.

Vous pouvez également l'utiliser comme ceci pour renvoyer une valeur par défaut:

(string ?? "").isEmpty ? "Default" : string!

3
Élégant ??? Vous avez essentiellement écrit "si la chaîne n'est pas nulle, sinon une chaîne vide et cet appel est vide sur cela ... Quelle déclaration logique.
Renetik

73

Vous pouvez peut-être utiliser la clause if-let-where:

Swift 3:

if let string = string, !string.isEmpty {
    /* string is not blank */
}

Swift 2:

if let string = string where !string.isEmpty {
    /* string is not blank */
}

2
Ne fonctionne pas avec Swift 2, obtenant cette erreur d'exécution, fatal error: unexpectedly found nil while unwrapping an Optional valuemais ma constante stringa une chaîne de données.
Nagendra Rao

3
Cela fonctionne dans Swift 3:if let string = string, !string.isEmpty { /* string is not blank */ }
EricS

1
@AmrLotfy guard letest une alternative si vous souhaitez mettre fin au flux de contrôle sous l'instruction. Cependant, rien n'est déballé dans la clause where ici (le! Est une négation booléenne)
Ryan

alors que diriez-vous de ça! str? .isEmpty au lieu de string = string où! string.isEmpty
Pankaj

28

Si vous utilisez Swift 2, voici un exemple que mon collègue a proposé, qui ajoute la propriété isNilOrEmpty sur les chaînes facultatives:

protocol OptionalString {}
extension String: OptionalString {}

extension Optional where Wrapped: OptionalString {
    var isNilOrEmpty: Bool {
        return ((self as? String) ?? "").isEmpty
    }
}

Vous pouvez ensuite utiliser isNilOrEmpty sur la chaîne facultative elle-même

func testNilOrEmpty() {
    let nilString:String? = nil
    XCTAssertTrue(nilString.isNilOrEmpty)

    let emptyString:String? = ""
    XCTAssertTrue(emptyString.isNilOrEmpty)

    let someText:String? = "lorem"
    XCTAssertFalse(someText.isNilOrEmpty)
}

Pouvez-vous s'il vous plaît clarifier ce que vous avez fait ici ou une ressource qui peut l'expliquer en détail. Comme pourquoi OptionalString est déclaré? Je ne reçois pas la syntaxe. Ce n'est pas comme l'implémentation normale d'extension So. Merci beaucoup d'avance
Vinayak Parmar

@VinayakParmar OptionalString est déclaré ici car le where Wrapped:doit spécifier un protocole et non un type.
Adam Johns

Peut - être que vous pouvez nommer isNilOrEmptyà hasValue(ou quelque chose comme ça) et d' inverser la logique
islam Q.

28

En utilisant le guard déclaration

J'utilisais Swift pendant un certain temps avant d'apprendre la guarddéclaration. Maintenant, je suis un grand fan. Il est utilisé de la même manière que l' ifinstruction, mais il permet un retour anticipé et permet simplement un code beaucoup plus propre en général.

Pour utiliser guard lorsque vous vérifiez qu'une chaîne n'est ni nulle ni vide, vous pouvez effectuer les opérations suivantes:

let myOptionalString: String? = nil

guard let myString = myOptionalString, !myString.isEmpty else {
    print("String is nil or empty.")
    return // or break, continue, throw
}

/// myString is neither nil nor empty (if this point is reached)
print(myString)

Cela déballe la chaîne facultative et vérifie qu'elle n'est pas du tout vide. S'il est nul (ou vide), vous revenez immédiatement de votre fonction (ou boucle) et tout ce qui suit est ignoré. Mais si l'instruction de garde réussit, vous pouvez utiliser en toute sécurité votre chaîne non emballée.

Voir également


Faites attention. print (myString) ne fonctionnera pas, si String est nul ou vide, car guard est conçu pour ne pas tomber après être entré dans la phase else.
Kang Byul

@KangByul, c'est correct et c'est l'intention de la logique ici. Vraisemblablement, si la chaîne est nilou vide, on ne voudrait pas appeler print(myString). Si vous aviez besoin de continuer l'exécution après a nilou vide String, vous utiliseriez if letplutôt que guard.
Suragch

Merci pour un éloge. Je sais, je dis juste à d'autres qui ne connaissent pas grand-chose à la garde.
Kang Byul

4
@KangByul Je ne comprends pas le point de votre commentaire "soyez prudent", je pense que cela effraie les gens d'une excellente solution, la déclaration de retour est clairement juste dans la déclaration guard else, je pense que vous devriez supprimer votre commentaire
Brian Ogden

16

Avec Swift 5, vous pouvez implémenter une Optionalextension pour Stringtype avec une propriété booléenne qui renvoie si une chaîne facultative n'a pas de valeur ou est vide:

extension Optional where Wrapped == String {

    var isNilOrEmpty: Bool {
        return self?.isEmpty ?? true
    }

}

Cependant, Stringimplémente la isEmptypropriété en se conformant au protocole Collection. Par conséquent, nous pouvons remplacer la contrainte générique du code précédent ( Wrapped == String) par une plus large ( Wrapped: Collection) afin que Array, Dictionaryet Setégalement bénéficier de notre nouvelle isNilOrEmptypropriété:

extension Optional where Wrapped: Collection {

    var isNilOrEmpty: Bool {
        return self?.isEmpty ?? true
    }

}

Utilisation avec Strings:

let optionalString: String? = nil
print(optionalString.isNilOrEmpty) // prints: true
let optionalString: String? = ""
print(optionalString.isNilOrEmpty) // prints: true
let optionalString: String? = "Hello"
print(optionalString.isNilOrEmpty) // prints: false

Utilisation avec Arrays:

let optionalArray: Array<Int>? = nil
print(optionalArray.isNilOrEmpty) // prints: true
let optionalArray: Array<Int>? = []
print(optionalArray.isNilOrEmpty) // prints: true
let optionalArray: Array<Int>? = [10, 22, 3]
print(optionalArray.isNilOrEmpty) // prints: false

Sources:


1
J'aime ça, le seul ajustement que je ferais est de le renommer de isNilOrEmptyà isEmptyOrNilpour qu'il corresponde au préfixe afin qu'il soit facilement trouvable via le même modèle pour la saisie semi-automatique. J'ai remarqué une plus grande adoption de cette extension par des collègues avec lesquels je travaille rien qu'en trouvant cela de cette façon.
Aaron

14
var str: String? = nil

if str?.isEmpty ?? true {
    print("str is nil or empty")
}

str = ""

if str?.isEmpty ?? true {
    print("str is nil or empty")
}

1
Élégant mais maladroit;), le "vrai" jette un peu l'
intution

9

Je sais qu'il y a beaucoup de réponses à cette question, mais aucune d'entre elles ne semble être aussi pratique que celle-ci (à mon avis) pour valider les UITextFielddonnées, ce qui est l'un des cas les plus courants d'utilisation:

extension Optional where Wrapped == String {
    var isNilOrEmpty: Bool {
        return self?.trimmingCharacters(in: .whitespaces).isEmpty ?? true
    }
}

Vous pouvez simplement utiliser

textField.text.isNilOrEmpty

Vous pouvez également ignorer .trimmingCharacters(in:.whitespaces)si vous ne considérez pas les espaces comme une chaîne vide ou l'utiliser pour des tests d'entrée plus complexes comme

var isValidInput: Bool {
    return !isNilOrEmpty && self!.trimmingCharacters(in: .whitespaces).characters.count >= MIN_CHARS
}

Excellente réponse, l'Op n'a pas précisé si les espaces blancs étaient considérés comme vides, alors voici ma version: extension publique Facultatif où Wrapped == String {var isEmptyOrNil: Bool {return (self ?? "") .isEmpty}}
sachadso

7

Je recommanderais.

if stringA.map(isEmpty) == false {
    println("blah blah")
}

mapapplique l'argument de fonction si l'option est .Some.
La capture de terrain de jeu montre également une autre possibilité avec le nouveau Swift 1.2 si la liaison est optionnelle.

entrez la description de l'image ici


7

Si vous souhaitez accéder à la chaîne de manière non facultative, vous devez utiliser la réponse de Ryan , mais si vous ne vous souciez que de la non-vacuité de la chaîne, mon raccourci préféré est

if stringA?.isEmpty == false {
    ...blah blah
}

Puisque ==fonctionne bien avec les booléens facultatifs, je pense que cela laisse le code lisible sans obscurcir l'intention originale.

Si vous voulez vérifier le contraire: si la chaîne est nilou "", je préfère vérifier les deux cas explicitement pour montrer l'intention correcte:

if stringA == nil || stringA?.isEmpty == true {
    ...blah blah
}

@ TruMan1 c'est correct, le but du premier exemple est de vérifier si la chaîne n'est pas vide.
Alex Pretzlav

4

SWIFT 3

extension Optional where Wrapped == String {

    /// Checks to see whether the optional string is nil or empty ("")
    public var isNilOrEmpty: Bool {
        if let text = self, !text.isEmpty { return false }
        return true
    }
}

Utilisez comme ceci sur une chaîne facultative:

if myString.isNilOrEmpty { print("Crap, how'd this happen?") } 

4

Swift 3 pour vérifier la chaîne vide de la meilleure façon

if !string.isEmpty{

// do stuff

}

2

Vous pouvez créer votre propre fonction personnalisée, si c'est quelque chose que vous espérez faire beaucoup.

func isBlank (optionalString :String?) -> Bool {
    if let string = optionalString {
        return string.isEmpty
    } else {
        return true
    }
}



var optionalString :String? = nil

if isBlank(optionalString) {
    println("here")
}
else {
    println("there")
}

2

Solution Swift 3 Utilisez la valeur optionnelle non emballée et comparez la valeur booléenne.

if (string?.isempty == true) {
    // Perform action
}

2

Utiliser isEmpty

"Hello".isEmpty  // false
"".isEmpty       // true

Utilisation de allSatisfy

extension String {
  var isBlank: Bool {
    return allSatisfy({ $0.isWhitespace })
  }
}

"Hello".isBlank        // false
"".isBlank             // true

Utilisation d'une chaîne facultative

extension Optional where Wrapped == String {
  var isBlank: Bool {
    return self?.isBlank ?? true
  }
}

var title: String? = nil
title.isBlank            // true
title = ""               
title.isBlank            // true

Référence: https://useyourloaf.com/blog/empty-strings-in-swift/


1

Créez une extension de classe String:

extension String
{   //  returns false if passed string is nil or empty
    static func isNilOrEmpty(_ string:String?) -> Bool
    {   if  string == nil                   { return true }
        return string!.isEmpty
    }
}// extension: String

Notez que cela retournera TRUE si la chaîne contient un ou plusieurs espaces. Pour traiter une chaîne vide comme "vide", utilisez ...

return string!.trimmingCharacters(in: CharacterSet.whitespaces).isEmpty

... au lieu. Cela nécessite Foundation.

Utilisez-le ainsi ...

if String.isNilOrEmpty("hello world") == true 
{   print("it's a string!")
}

1

Swift 3 Cela fonctionne bien pour vérifier si la chaîne est vraiment vide. Parce que isEmpty renvoie true lorsqu'il y a un espace.

extension String {
    func isEmptyAndContainsNoWhitespace() -> Bool {
        guard self.isEmpty, self.trimmingCharacters(in: .whitespaces).isEmpty
            else {
               return false
        }
        return true
    }
}

Exemples:

let myString = "My String"
myString.isEmptyAndContainsNoWhitespace() // returns false

let myString = ""
myString.isEmptyAndContainsNoWhitespace() // returns true

let myString = " "
myString.isEmptyAndContainsNoWhitespace() // returns false

1

Vous devriez faire quelque chose comme ceci:
if !(string?.isEmpty ?? true) { //Not nil nor empty }

Nil L'opérateur de coalescence vérifie si l'option n'est pas nulle, dans le cas où il n'est pas nul, il vérifie alors sa propriété, dans ce cas est vide. Parce que cette option peut être nil, vous fournissez une valeur par défaut qui sera utilisée lorsque votre option est nulle.


1

Il s'agit d'une solution générale pour tous les types conformes au Collectionprotocole, qui comprend String:

extension Optional where Wrapped: Collection {
    var isNilOrEmpty: Bool {
        self?.isEmpty ?? true
    }
}

0

Lors du passage des valeurs de la base de données locale au serveur et vice versa, j'avais trop de problèmes avec les? Et les! Et autres.

J'ai donc créé un utilitaire Swift3.0 pour gérer les cas nuls et je peux presque totalement éviter les? Et! 'S dans le code.

func str(_ string: String?) -> String {
    return (string != nil ? string! : "")
}

Ex:-

Avant :

    let myDictionary: [String: String] = 
                      ["title": (dbObject?.title != nil ? dbObject?.title! : "")]

Après :

    let myDictionary: [String: String] = 
                        ["title": str(dbObject.title)]

et quand il est nécessaire de vérifier une chaîne valide,

    if !str(dbObject.title).isEmpty {
        //do stuff
    }

Cela m'a évité d'avoir à passer par la peine d'ajouter et de supprimer de nombreux? Et! Après avoir écrit du code qui a du sens.


0

Utilisez l'opérateur ternaire (également appelé opérateur conditionnel C++ forever!):

if stringA != nil ? stringA!.isEmpty == false : false { /* ... */ }

Le stringA!déballage forcé ne se produit que lorsque stringA != nil, donc c'est sûr. La == falseverbosité est un peu plus lisible qu'un autre point d'exclamation !(stringA!.isEmpty).

Personnellement, je préfère une forme légèrement différente:

if stringA == nil ? false : stringA!.isEmpty == false { /* ... */ }

Dans l'instruction ci-dessus, il est immédiatement très clair que le ifbloc entier ne s'exécute pas lorsqu'une variable est nil.


0

utile pour obtenir la valeur de UITextField et vérifier la nil& emptychaîne

@IBOutlet weak var myTextField: UITextField!

Voici votre fonction (lorsque vous appuyez sur a button) qui obtient une chaîne de UITextField et fait d'autres choses

@IBAction func getStringFrom_myTextField(_ sender: Any) {

guard let string = myTextField.text, !(myTextField.text?.isEmpty)!  else { return }
    //use "string" to do your stuff.
}

Cela prendra en charge la nilvaleur ainsi que la emptychaîne.

Cela a parfaitement bien fonctionné pour moi.


0

À mon avis, la meilleure façon de vérifier la chaîne nulle et vide est de prendre le nombre de chaînes.

var nilString : String?
print(nilString.count) // count is nil

var emptyString = ""
print(emptyString.count) // count is 0

// combine both conditions for optional string variable
if string?.count == nil || string?.count == 0 {
   print("Your string is either empty or nil")
}

-4

vous pouvez utiliser cette fonction

 class func stringIsNilOrEmpty(aString: String) -> Bool { return (aString).isEmpty }

2
Pas un utilisateur rapide; pourriez-vous expliquer pourquoi cela ne lève pas d'exception si nul est passé?
Foon

Il ne nillève pas d'exception car vous ne pouvez pas du tout passer dans cette fonction (sauf depuis objc, auquel cas il plantera effectivement).
Alfonso

Cela ne répond pas à la question. Il ne vérifie pas la valeur nulle car il n'accepte pas une option
Wayne Ellery
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.