Überprüfen Sie die Zeichenfolge auf null und leer

134

Gibt es eine Möglichkeit, Zeichenfolgen für nilund ""in Swift zu überprüfen ? In Rails kann ich blank()überprüfen.

Ich habe dies derzeit, aber es scheint übertrieben:

    if stringA? != nil {
        if !stringA!.isEmpty {
            ...blah blah
        }
    }
Dean
quelle
1
Die Antworten von (@sutra und @ imanou-petit) sind besser.
Herr Ming

Antworten:

211

Wenn Sie mit optionalen Strings arbeiten, funktioniert dies:

(string ?? "").isEmpty

Der ??Null-Koaleszenz-Operator gibt die linke Seite zurück, wenn er nicht Null ist, andernfalls gibt er die rechte Seite zurück.

Sie können es auch so verwenden, um einen Standardwert zurückzugeben:

(string ?? "").isEmpty ? "Default" : string!
jrc
quelle
3
Elegant ??? Sie haben im Grunde geschrieben: "Wenn die Zeichenfolge nicht null ist, ist die Zeichenfolge leer und dieser Aufruf ist leer ... Was für eine logische Aussage.
Renetik
73

Sie könnten vielleicht die if-let-where-Klausel verwenden:

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 */
}
Ryan
quelle
2
Funktioniert nicht mit Swift 2, da dieser Laufzeitfehler auftritt, fatal error: unexpectedly found nil while unwrapping an Optional valueaber meine Konstante stringenthält Zeichenfolgendaten.
Nagendra Rao
3
Dies funktioniert in Swift 3:if let string = string, !string.isEmpty { /* string is not blank */ }
EricS
1
@AmrLotfy guard letist eine Alternative, wenn Sie den Kontrollfluss unterhalb der Anweisung beenden möchten. Allerdings wird in der where-Klausel hier nichts ausgepackt (das! Ist eine boolesche Negation)
Ryan
Also, wie wäre es damit! str? .isEmpty statt string = string wo! string.isEmpty
Pankaj
28

Wenn Sie Swift 2 verwenden, ist hier ein Beispiel, das mein Kollege entwickelt hat und das die Eigenschaft isNilOrEmpty für optionale Zeichenfolgen hinzufügt:

protocol OptionalString {}
extension String: OptionalString {}

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

Sie können dann isNilOrEmpty für die optionale Zeichenfolge selbst verwenden

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

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

    let someText:String? = "lorem"
    XCTAssertFalse(someText.isNilOrEmpty)
}
Ken Ko
quelle
Können Sie bitte klarstellen, was Sie hier getan haben, oder eine Ressource, die dies im Detail erklären kann? Zum Beispiel, warum OptionalString deklariert ist? Ich verstehe die Syntax nicht. Es ist nicht wie bei einer normalen Erweiterungsimplementierung. Vielen Dank im Voraus
Vinayak Parmar
@VinayakParmar OptionalString wird hier deklariert, da where Wrapped:ein Protokoll und kein Typ angegeben werden muss.
Adam Johns
Vielleicht könnten Sie nennen isNilOrEmptyzu hasValue(oder so ähnlich) und umgekehrt die Logik
Islam Q.
27

Verwendung der guardAnweisung

Ich habe Swift eine Weile benutzt, bevor ich von der guardAussage erfahren habe . Jetzt bin ich ein großer Fan. Es wird ähnlich wie die ifAnweisung verwendet, ermöglicht jedoch eine frühzeitige Rückgabe und sorgt im Allgemeinen für viel saubereren Code.

Sie können Folgendes tun, um bei der Überprüfung sicherzustellen, dass eine Zeichenfolge weder null noch leer ist:

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)

Dadurch wird die optionale Zeichenfolge ausgepackt und auf einmal überprüft, ob sie nicht leer ist. Wenn es null (oder leer) ist, kehren Sie sofort von Ihrer Funktion (oder Schleife) zurück und alles danach wird ignoriert. Wenn die Guard-Anweisung jedoch erfolgreich ist, können Sie Ihre unverpackte Zeichenfolge sicher verwenden.

Siehe auch

Suragch
quelle
Achtung. print (myString) wird nicht ausgeführt, wenn String null oder leer ist, da der Schutz so ausgelegt ist, dass er nach dem Eintritt in die else-Phase nicht herunterfällt.
Kang Byul
@ KangByul, das ist richtig und ist die Absicht der Logik hier. Vermutlich, wenn die Zeichenfolge nilleer oder leer ist, möchte man nicht aufrufen print(myString). Wenn Sie die Ausführung nach einem niloder leer fortsetzen Stringmüssten, würden Sie if leteher als verwenden guard.
Suragch
Danke für ein Lob. Ich weiß, ich erzähle nur anderen, die nicht viel über Wache wissen.
Kang Byul
3
@KangByul Ich verstehe den Sinn Ihres "Vorsicht" -Kommentars nicht. Ich denke, es schreckt die Leute vor einer großartigen Lösung ab. Die Rückgabeerklärung stimmt eindeutig mit der Guard-else-Erklärung überein. Ich denke, Sie sollten Ihren Kommentar löschen
Brian Ogden
16

Mit Swift 5 können Sie eine OptionalErweiterung für Stringtype mit einer booleschen Eigenschaft implementieren , die zurückgegeben wird, wenn eine optionale Zeichenfolge keinen Wert hat oder leer ist:

extension Optional where Wrapped == String {

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

}

Allerdings Stringimplementiert isEmptyEigenschaft von zu Protokoll entspricht Collection. Deshalb können wir den vorherigen Code des generische Einschränkung (ersetzen Wrapped == String) mit einem breiteren ein ( Wrapped: Collection) , so dass Array, Dictionaryund Setauch unsere neuen profitieren isNilOrEmptyEigenschaft:

extension Optional where Wrapped: Collection {

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

}

Verwendung mit 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

Verwendung mit 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

Quellen:

Imanou Petit
quelle
1
Ich mag diese, die nur zwicken ich machen würde , ist es umbenennen aus , isNilOrEmptyum isEmptyOrNildas Präfix übereinstimmen , so dass es für die automatische Vervollständigung über das gleiche Muster leicht auffindbar ist. Ich habe festgestellt, dass diese Erweiterung von Kollegen, mit denen ich zusammenarbeite, mehr angenommen wird, nur weil sie es so finden.
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")
}
Sutra
quelle
1
Elegant, aber umständlich;), die "wahre" Art wirft die Intution ab
TruMan1
9

Ich weiß, dass es viele Antworten auf diese Frage gibt, aber keine davon scheint (meiner Meinung nach) so bequem zu sein, um UITextFieldDaten zu validieren , was einer der häufigsten Fälle für die Verwendung ist:

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

Sie können einfach verwenden

textField.text.isNilOrEmpty

Sie können das auch überspringen, .trimmingCharacters(in:.whitespaces)wenn Sie Leerzeichen nicht als leere Zeichenfolge betrachten, oder es für komplexere Eingabetests wie verwenden

var isValidInput: Bool {
    return !isNilOrEmpty && self!.trimmingCharacters(in: .whitespaces).characters.count >= MIN_CHARS
}
Sir Codesalot
quelle
Tolle Antwort, die Operation hat nicht genau angegeben, ob Leerzeichen als leer gezählt wurden. Hier ist meine Version: public extension Optional where Wrapped == String {var isEmptyOrNil: Bool {return (self ?? "") .isEmpty}}
sachadso
7

Ich würde empfehlen.

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

mapwendet das Funktionsargument an, wenn das optionale ist .Some.
Die Spielplatzaufnahme zeigt auch eine andere Möglichkeit mit dem neuen Swift 1.2, wenn optionale Bindung zugelassen wird.

Geben Sie hier die Bildbeschreibung ein

Preis Ringo
quelle
7

Wenn Sie als nicht optional auf die Zeichenfolge zugreifen möchten, sollten Sie Ryans Antwort verwenden . Wenn Sie sich jedoch nur um die Nichtleere der Zeichenfolge kümmern, ist meine bevorzugte Abkürzung dafür

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

Schon seit == mit optionalen Booleschen Werten gut funktioniert, bleibt der Code meiner Meinung nach lesbar, ohne die ursprüngliche Absicht zu verschleiern.

Wenn Sie das Gegenteil überprüfen möchten: Wenn die Zeichenfolge niloder ist "", bevorzuge ich es, beide Fälle explizit zu überprüfen, um die richtige Absicht zu zeigen:

if stringA == nil || stringA?.isEmpty == true {
    ...blah blah
}
Alex Pretzlav
quelle
@ TruMan1 das stimmt, das Ziel des ersten Beispiels ist es zu überprüfen, ob die Zeichenfolge nicht leer ist.
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
    }
}

Verwenden Sie diese Option für eine optionale Zeichenfolge:

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

Swift 3 Zum Überprüfen von Empty String best way

if !string.isEmpty{

// do stuff

}
Anas
quelle
2

Sie können Ihre eigene benutzerdefinierte Funktion erstellen, wenn Sie dies erwarten.

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")
}
vol7ron
quelle
2

Swift 3-Lösung Verwenden Sie den optionalen entpackten Wert und vergleichen Sie ihn mit dem Booleschen Wert.

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

Verwenden von isEmpty

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

AllSatisfy verwenden

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

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

Verwenden eines optionalen Strings

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

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

Referenz: https://useyourloaf.com/blog/empty-strings-in-swift/

raaz
quelle
1

Erstellen Sie eine String-Klassenerweiterung:

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

Beachten Sie, dass dies TRUE zurückgibt, wenn die Zeichenfolge ein oder mehrere Leerzeichen enthält. Um eine leere Zeichenfolge als "leer" zu behandeln, verwenden Sie ...

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

... stattdessen. Dies erfordert Foundation.

Verwenden Sie es so ...

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

Swift 3 Dies funktioniert gut, um zu überprüfen, ob die Zeichenfolge wirklich leer ist. Weil isEmpty true zurückgibt, wenn ein Leerzeichen vorhanden ist.

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

Beispiele:

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

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

let myString = " "
myString.isEmptyAndContainsNoWhitespace() // returns false
FredFlinstone
quelle
1

Sie sollten so etwas tun:
if !(string?.isEmpty ?? true) { //Not nil nor empty }

Der Null-Koaleszenz-Operator prüft, ob das Optionale nicht Null ist. Falls es nicht Null ist, prüft er seine Eigenschaft, in diesem Fall ist Leer. Da diese Option Null sein kann, geben Sie einen Standardwert an, der verwendet wird, wenn Ihre Option Null ist.

Dominik Babić
quelle
1

Dies ist eine allgemeine Lösung für alle Typen, die dem CollectionProtokoll entsprechen. Dazu gehören String:

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

Beim Übergeben von Werten von der lokalen Datenbank an den Server und umgekehrt hatte ich zu viele Probleme mit? 'S und!' S und was nicht.

Also habe ich ein Swift3.0-Dienstprogramm erstellt, um Nullfälle zu behandeln, und ich kann? S und! Im Code fast vollständig vermeiden.

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

Ex:-

Vor :

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

Nach dem :

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

und wenn es erforderlich ist, nach einer gültigen Zeichenfolge zu suchen,

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

Dies ersparte mir die Mühe, nach dem Schreiben von Code, der vernünftigerweise Sinn macht, zahlreiche? 'Und!' S hinzuzufügen und zu entfernen.

Nikhil Mathew
quelle
0

Verwenden Sie den ternären Operator (auch als bedingter Operator bezeichnet C++ forever!):

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

Das stringA!gewaltsame Auspacken erfolgt nur dann stringA != nil, wenn es sicher ist. Die == falseAusführlichkeit ist etwas lesbarer als ein weiteres Ausrufezeichen in!(stringA!.isEmpty) .

Ich persönlich bevorzuge eine etwas andere Form:

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

In der obigen Anweisung wird sofort sehr deutlich, dass der gesamte ifBlock nicht ausgeführt wird, wenn eine Variable vorhanden ist nil.

Gary
quelle
0

hilfreich, wenn Sie einen Wert von UITextField abrufen und nach nil& emptystring suchen

@IBOutlet weak var myTextField: UITextField!

Hier ist Ihre Funktion (wenn Sie auf eine tippen button), die einen String von UITextField erhält und einige andere Dinge erledigt

@IBAction func getStringFrom_myTextField(_ sender: Any) {

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

Dies kümmert sich sowohl um den nilWert als auch um die emptyZeichenfolge.

Es hat perfekt für mich funktioniert.

Soropromo
quelle
0

Meiner Meinung nach ist die beste Möglichkeit, die Null- und Leerzeichenfolge zu überprüfen, die Anzahl der Zeichenfolgen.

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")
}
yo2bh
quelle
-4

Sie können diese Funktion verwenden

 class func stringIsNilOrEmpty(aString: String) -> Bool { return (aString).isEmpty }
Ahmed Khemiri
quelle
2
Kein schneller Benutzer; Können Sie erklären, warum dies keine Ausnahme auslöst, wenn Null übergeben wird?
Foon
Es wird keine Ausnahme nilausgelöst, da Sie diese Funktion überhaupt nicht ausführen können (außer von objc, in welchem ​​Fall sie tatsächlich abstürzt).
Alfonso
Dies beantwortet die Frage nicht. Es prüft nicht auf Null, da es kein optionales akzeptiert
Wayne Ellery