Sprawdź ciąg pod kątem zera i pustego


Odpowiedzi:


221

Jeśli masz do czynienia z opcjonalnymi ciągami znaków, działa to:

(string ?? "").isEmpty

??Operator zwraca nil koalescencyjny z lewej strony, jeżeli jest to non-zero, w przeciwnym wypadku zwraca prawą stronę.

Możesz również użyć tego w ten sposób, aby zwrócić wartość domyślną:

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

74

Być może możesz użyć klauzuli 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
Nie działa ze Swift 2, otrzymując ten błąd czasu wykonywania, fatal error: unexpectedly found nil while unwrapping an Optional valueale moja stała stringma dane łańcuchowe.
Nagendra Rao,

3
Działa to w Swift 3:if let string = string, !string.isEmpty { /* string is not blank */ }
EricS

1
@AmrLotfy guard letjest alternatywą, jeśli chcesz zakończyć przepływ sterowania poniżej instrukcji. Jednak nic nie jest rozpakowywane w klauzuli gdzie tutaj (! Jest logiczną negacją)
Ryan,

a co powiesz na to! str? .isEmpty zamiast string = string gdzie! string.isEmpty
Pankaj

28

Jeśli używasz Swift 2, oto przykład, który wymyślił mój kolega, który dodaje właściwość isNilOrEmpty do opcjonalnych ciągów znaków:

protocol OptionalString {}
extension String: OptionalString {}

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

Następnie możesz użyć isNilOrEmpty na samym opcjonalnym ciągu

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

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

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

Czy możesz wyjaśnić, co tutaj zrobiłeś, lub jakieś źródło, które może to szczegółowo wyjaśnić. Na przykład, dlaczego zadeklarowano ciąg OptionalString? Nie otrzymuję składni. To nie jest jak normalna implementacja rozszerzenia. Z góry dziękuję
Vinayak Parmar

@VinayakParmar OptionalString jest tutaj zadeklarowana, ponieważ where Wrapped:musi określać protokół, a nie typ.
Adam Johns

Być może można wymienić isNilOrEmptyna hasValue(lub coś takiego) i odwrócić logikę
Islam Q.

28

Korzystanie z guardinstrukcji

Używałem Swift przez jakiś czas, zanim dowiedziałem się o guardoświadczeniu. Teraz jestem wielkim fanem. Jest używany podobnie do ifinstrukcji, ale umożliwia wczesny powrót i ogólnie zapewnia znacznie czystszy kod.

Aby użyć guard podczas sprawdzania, czy łańcuch nie jest zerowy ani pusty, możesz wykonać następujące czynności:

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)

Spowoduje to rozpakowanie opcjonalnego ciągu i sprawdzenie, czy nie jest on jednocześnie pusty. Jeśli jest nil (lub pusty), natychmiast wracasz z funkcji (lub pętli) i wszystko po niej jest ignorowane. Ale jeśli instrukcja guard przejdzie pomyślnie, możesz bezpiecznie użyć rozpakowanego ciągu.

Zobacz też


bądź ostrożny. print (myString) nie będzie działać, jeśli String jest zerowy lub pusty, ponieważ ochrona została zaprojektowana tak, aby nie spadła po wejściu w fazę else.
Kang Byul

@KangByul, zgadza się i jest celem tej logiki. Przypuszczalnie, jeśli łańcuch jest nillub pusty, nie chciałoby się dzwonić print(myString). Jeśli potrzebujesz kontynuować wykonywanie po a nillub pustym miejscu String, użyj if letzamiast guard.
Suragch

Dzięki za pochwałę. Wiem, po prostu mówię innym, którzy niewiele wiedzą o straży.
Kang Byul

4
@KangByul Nie rozumiem sensu twojego komentarza "bądź ostrożny", myślę, że odstrasza ludzi od świetnego rozwiązania, oświadczenie zwrotu jest wyraźnie słuszne w oświadczeniu strażnika else, myślę, że powinieneś usunąć swój komentarz
Brian Ogden

18

Dzięki Swift 5 możesz zaimplementować Optionalrozszerzenie Stringtypu z właściwością logiczną, która zwraca, jeśli opcjonalny ciąg nie ma wartości lub jest pusty:

extension Optional where Wrapped == String {

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

}

Jednak Stringimplementuje isEmptywłaściwość zgodnie z protokołem Collection. Dlatego możemy zastąpić ogólne ograniczenie poprzednim kodzie'S ( Wrapped == String) z szerszym jeden ( Wrapped: Collection), dzięki czemu Array, Dictionarya Settakże korzystać z nowego isNilOrEmptywłaściwość:

extension Optional where Wrapped: Collection {

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

}

Użycie z 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

Użycie z 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

Źródła:


1
Podoba mi się to, jedyną poprawką, jaką bym zrobił, jest zmiana nazwy z isNilOrEmptyna, isEmptyOrNilaby pasowała do prefiksu, aby można go było łatwo znaleźć za pomocą tego samego wzorca dla autouzupełniania. Zauważyłem, że to rozszerzenie jest bardziej popularne od kolegów, z którymi pracuję, tylko od tego, jak znaleźli to w ten sposób.
Aaron

15
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
Eleganckie, ale niezręczne;), „prawdziwa” trochę wyrzuca intucję
TruMan1

9

Wiem, że istnieje wiele odpowiedzi na to pytanie, ale żadna z nich nie wydaje się być tak wygodna (moim zdaniem) do walidacji UITextFielddanych, co jest jednym z najczęstszych przypadków korzystania z nich:

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

Możesz po prostu użyć

textField.text.isNilOrEmpty

Możesz również pominąć, .trimmingCharacters(in:.whitespaces)jeśli nie traktujesz białych znaków jako pustego ciągu lub użyć go do bardziej złożonych testów wejściowych, takich jak

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

Świetna odpowiedź, operacja nie precyzowała, czy białe znaki są liczone jako puste, więc oto moja wersja: rozszerzenie publiczne Opcjonalne gdzie Wrapped == String {var isEmptyOrNil: Bool {return (self ?? "") .isEmpty}}
sachadso

7

Chciałbym polecić.

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

mapstosuje argument funkcji, jeśli opcjonalny jest .Some.
Przechwytywanie placu zabaw pokazuje również inną możliwość z nowym Swift 1.2, jeśli pozwolisz na opcjonalne wiązanie.

wprowadź opis obrazu tutaj


7

Jeśli chcesz uzyskać dostęp do ciągu jako nieobowiązkowego, powinieneś użyć odpowiedzi Ryana , ale jeśli zależy ci tylko na braku pustości ciągu, moim preferowanym skrótem jest to

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

Ponieważ ==działa dobrze z opcjonalnymi wartościami logicznymi, myślę, że pozostawia to kod czytelny bez przesłania pierwotnego zamiaru.

Jeśli chcesz sprawdzić coś odwrotnego: jeśli ciąg to nillub "", wolę wyraźnie sprawdzić oba przypadki, aby pokazać prawidłową intencję:

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

@ TruMan1, to prawda, celem pierwszego przykładu jest sprawdzenie, czy ciąg nie jest pusty.
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
    }
}

Użyj w ten sposób na opcjonalnym ciągu:

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

4

Swift 3 Najlepszym sposobem sprawdzenia pustego sznurka

if !string.isEmpty{

// do stuff

}

2

Możesz stworzyć własną funkcję niestandardową, jeśli spodziewasz się dużo pracy.

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

Rozwiązanie Swift 3 Użyj opcjonalnej nieopakowanej wartości i porównaj z wartością logiczną.

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

2

Korzystanie z isEmpty

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

Korzystanie z allSatisfy

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

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

Korzystanie z opcjonalnego ciągu znaków

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

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

Źródła: https://useyourloaf.com/blog/empty-strings-in-swift/


2

Jest to ogólne rozwiązanie dla wszystkich typów zgodnych z Collectionprotokołem, które obejmuje String:

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

1

Utwórz rozszerzenie klasy 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

Zwróć uwagę, że zwróci to wartość TRUE, jeśli ciąg zawiera jeden lub więcej odstępów. Aby traktować pusty ciąg jako „pusty”, użyj ...

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

... zamiast. To wymaga Fundacji.

Użyj go w ten sposób ...

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

1

Swift 3 Działa to dobrze, aby sprawdzić, czy łańcuch jest naprawdę pusty. Ponieważ isEmpty zwraca wartość true, gdy występuje spacja.

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

Przykłady:

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

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

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

1

Powinieneś zrobić coś takiego:
if !(string?.isEmpty ?? true) { //Not nil nor empty }

Operator łączenia zerowego sprawdza, czy argument opcjonalny nie jest zerowy, w przypadku, gdy nie jest zerowy, sprawdza następnie jego właściwość, w tym przypadku isEmpty. Ponieważ ta opcja może wynosić zero, podajesz wartość domyślną, która będzie używana, gdy opcja jest równa zero.


1

Moim zdaniem najlepszym sposobem sprawdzenia ciągów zerowych i pustych jest obliczenie liczby ciągów.

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")
}

0

Mając do czynienia z przekazywaniem wartości z lokalnej bazy danych do serwera i odwrotnie, miałem zbyt wiele problemów z? I !, a co nie.

Dlatego stworzyłem narzędzie Swift3.0 do obsługi przypadków zerowych i mogę prawie całkowicie uniknąć znaków? I! W kodzie.

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

Dawny:-

Przed :

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

Po :

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

i kiedy trzeba sprawdzić poprawny ciąg,

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

To zaoszczędziło mi kłopotów z dodawaniem i usuwaniem wielu znaków? I! Po napisaniu kodu, który ma sens.


0

Użyj operatora trójargumentowego (znanego również jako operator warunkowy C++ forever!):

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

stringA!Siły Unwrapping dzieje tylko wtedy stringA != nil, więc jest bezpieczne. Szczegółowość == falsejest nieco bardziej czytelna niż kolejny wykrzyknik w !(stringA!.isEmpty).

Osobiście wolę nieco inną formę:

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

W powyższym stwierdzeniu jest od razu bardzo jasne, że cały ifblok nie jest wykonywany, gdy zmienna jest nil.


0

pomocny podczas pobierania wartości z UITextField i sprawdzanie nili emptyłańcuch

@IBOutlet weak var myTextField: UITextField!

Oto twoja funkcja (po dotknięciu a button), która pobiera ciąg z UITextField i wykonuje inne rzeczy

@IBAction func getStringFrom_myTextField(_ sender: Any) {

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

To zajmie się zarówno nilwartością, jak i emptyciągiem znaków.

U mnie zadziałało doskonale.


-4

możesz użyć tej funkcji

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

2
Nie jest to szybki użytkownik; czy możesz wyjaśnić, dlaczego to nie zgłasza wyjątku, jeśli podano nil?
Foon

Nie nilzgłasza wyjątku, ponieważ nie można w ogóle przejść do tej funkcji (z wyjątkiem objc, w którym to przypadku rzeczywiście ulegnie awarii).
Alfonso

To nie odpowiada na pytanie. Nie sprawdza nilu, ponieważ nie akceptuje opcji opcjonalnej
Wayne Ellery
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.