Перевірте рядок на нуль та порожній


134

Чи є спосіб перевірити рядки для nilта ""в Swift? У Rails я можу використовувати blank()для перевірки.

У мене зараз це є, але це здається непосильним:

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


1
Відповіді (@sutra та @ imanou-petit) краще.
— Містер Мінг

Відповіді:


211

Якщо ви маєте справу з додатковими рядками, це працює:

(string ?? "").isEmpty

Оператор ??злиття нуля повертає ліву частину, якщо вона не є нульовою, інакше повертає праву частину.

Ви також можете використовувати його так, щоб повернути значення за замовчуванням:

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

3
Елегантний ??? Ви в основному написали "якщо рядок не є нульовою порожньою рядком, і цей виклик порожній на тому ... Яке логічне твердження"
— Renetik

73

Можливо, ви можете використовувати пункт if-let-where:

Швидкий 3:

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

Швидкий 2:

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

2
Не працює з Swift 2, отримуючи цю помилку часу виконання, fatal error: unexpectedly found nil while unwrapping an Optional valueале моя константа stringмає рядкові дані.
— Nagendra Rao

3
Це працює у Swift 3:if let string = string, !string.isEmpty { /* string is not blank */ }
— EricS

1
@AmrLotfy guard let- це альтернатива, якщо ви хочете припинити потік управління під оператором. Однак нічого не розгортається в пункті де тут (! - бульне заперечення)
— Райан

так як щодо цього! str? .isEmpty замість string = string where! string.isEmpty
— Панкай

28

Якщо ви використовуєте Swift 2, ось приклад, який придумав мій колега, який додає властивість isNilOrEmpty на необов'язкові рядки:

protocol OptionalString {}
extension String: OptionalString {}

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

Потім ви можете використовувати isNilOrEmpty у самому необов'язковому рядку

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

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

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

Чи можете ви поясніть, що ви тут робили, або якийсь ресурс, який може детально пояснити це. Як, чому оголошується OptionalString? Я не отримую синтаксису. Це не подобається нормальній реалізації розширення. Дякую заздалегідь
— Vinayak Parmar

@VinayakParmar OptionalString декларується тут, оскільки where Wrapped:вказується протокол, а не тип.
— Адам Джонс

Може бути , ви могли б назвати , isNilOrEmptyщоб hasValue(або що - то в цьому роді) і зворотну логіку
— Islam Q.

28

Використання guardвисловлювання

Я деякий час користувався Swift, перш ніж дізнався про guardтвердження. Зараз я великий фанат. Він використовується аналогічно ifтвердженню, але він дозволяє швидко повернутись і просто робить набагато більш чистим код в цілому.

Щоб використовувати захист під час перевірки, щоб переконатися, що рядок не є ні нульовою, ні порожньою, ви можете зробити наступне:

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)

Це розгортає необов’язковий рядок і перевіряє, чи не одразу він порожній. Якщо він нульовий (або порожній), ви повертаєтесь зі своєї функції (або циклу) негайно, і все після її ігнорування. Але якщо заява про захист пройде, то ви можете сміливо використовувати розпакований рядок.

Дивитися також


будь обережний. print (myString) не запуститься, якщо String є нульовим або порожнім, оскільки захист призначений для того, щоб не впасти після того, як вступить у фазу else.
— Кан Бюль

@KangByul, це правильно і в цьому полягає наміри логіки. Імовірно, якщо рядок nilпорожній або порожній, дзвонити не хочеться print(myString). Якщо вам потрібно було продовжити виконання після nilабо порожнього String, ви скористаєтесь, if letа не guard.
— Сурагч

Дякую за хвалу. Я знаю, я просто кажу іншим, хто не знає багато про охорону.
— Кан Бюль

4
@KangByul Я не розумію суть вашого коментаря "будьте обережні", я думаю, що це відлякує людей від чудового рішення, заява про повернення явно правильна в заяві іншої охорони, я думаю, ви повинні видалити свій коментар
— Брайан Огден

16

За допомогою Swift 5 ви можете реалізувати Optionalрозширення для Stringтипу з булевим властивістю, яке повертається, якщо необов'язковий рядок не має значення або порожній:

extension Optional where Wrapped == String {

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

}

Однак Stringреалізує isEmptyвластивість, дотримуючись протоколу Collection. Тому ми можемо замінити загальне обмеження попереднього коду ( Wrapped == String) на більш широке ( Wrapped: Collection), так щоArray , Dictionaryа Setтакож виграло наше нове isNilOrEmptyвластивість:

extension Optional where Wrapped: Collection {

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

}

Використання з 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

Використання з 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

Джерела:


1
Мені це подобається, єдиний твіт, який я б зробив, - це перейменувати його isNilOrEmptyна, isEmptyOrNilщоб відповідати префіксу, щоб його легко можна було знайти за допомогою тієї ж схеми для автозаповнення. Я помітив більше прийняття цього розширення від колег, з якими працюю, лише від них, які вважають це таким чином.
— Аарон

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
Елегантний, але незграбний;) "справжня" різновид кидає інтуїцію
— TruMan1

9

Я знаю, що існує багато відповідей на це питання, але жодна з них не здається такою зручною, як це (на мій погляд) для перевірки UITextFieldданих, що є одним із найпоширеніших випадків його використання:

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

Можна просто використовувати

textField.text.isNilOrEmpty

Ви також можете пропустити параметр, .trimmingCharacters(in:.whitespaces)якщо ви не вважаєте пробіли порожніми рядками або використовувати їх для більш складних вхідних тестів, таких як

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

Чудова відповідь, Op не уточнив, чи пробіли, де вважаються порожніми, ось ось моя версія: публічне розширення Необов’язково, де Wrapped == String {var isEmptyOrNil: Bool {return (self ?? "") .isEmpty}}
— sachadso

7

Я б рекомендував.

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

mapзастосовує аргумент функції, якщо необов'язковий .Some.
Захоплення ігрового майданчика також показує ще одну можливість з новим Swift 1.2, якщо дозволити необов'язкові прив’язки.

введіть тут опис зображення


7

Якщо ви хочете отримати доступ до рядка як необов'язковий, вам слід скористатись відповіддю Райана , але якщо ви дбаєте лише про порожнечу рядка, моїм кращим скороченням для цього є

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

Оскільки ==відмінно працює з додатковими булевими, я думаю, що це залишає код читабельним, не приховуючи початковий намір.

Якщо ви хочете , щоб перевірити зворотне: якщо рядок nilабо "", я вважаю за краще , щоб перевірити обидва випадки явно , щоб показати правильне намір:

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

@ TruMan1 це правильно, мета першого прикладу - перевірити, чи рядок не порожній.
— Олексій Прецлав

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

Використовуйте так у додатковому рядку:

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

4

Swift 3 Для найкращої перевірки Порожня струна

if !string.isEmpty{

// do stuff

}

2

Ви можете створити власну власну функцію, якщо це те, що ви очікуєте зробити багато.

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

Рішення Swift 3 Використовуйте необов’язкове розгорнуте значення та перевірте булеве значення.

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

2

Використання isEmpty

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

Використовуючи allSatisfy

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

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

Використання необов'язкового рядка

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

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

Довідка: https://useyourloaf.com/blog/empty-strings-in-swift/


1

Створіть розширення класу 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

Зауважте, що це поверне TRUE, якщо рядок містить один або кілька пробілів. Щоб трактувати порожній рядок як "порожній", використовуйте ...

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

... замість цього. Для цього потрібен фонд.

Використовуйте його таким чином ...

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

1

Swift 3 Це добре працює, щоб перевірити, чи рядок справді порожній. Тому що isEmpty повертає істину, коли є пробіл.

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

Приклади:

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

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

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

1

Ви повинні зробити щось подібне:
if !(string?.isEmpty ?? true) { //Not nil nor empty }

Оператор злиття Nil перевіряє, якщо опція не є нульовою, якщо вона не є нульовою, то перевіряє її властивість, у цьому випадку є порожнім. Оскільки ця опція може бути нульовою, ви надаєте значення за замовчуванням, яке буде використовуватися, коли ваш необов'язковий - нульовий.


1

Це загальне рішення для всіх типів, що відповідають Collectionпротоколу, яке включає String:

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

0

Маючи справу з передачею значень з локального db на сервер і навпаки, у мене виникли занадто великі проблеми з? S і !, а що ні.

Тому я зробив утиліту Swift3.0 для обробки нульових випадків, і я можу майже повністю уникнути? 'І! В коді.

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

Наприклад: -

Перед:

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

Після:

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

і коли потрібно перевірити правильність рядка,

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

Це врятувало мене, коли мені довелося переживати проблеми з додаванням та видаленням численних? І та! Після написання коду, що має сенс.


0

Використовуйте потрійний оператор (також відомий як умовний оператор C++ forever!):

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

stringA!Сила-розгортання відбувається тільки тоді , коли stringA != nil, так що це безпечно. == falseПодробиця кілька більш читабельним , ніж ще один знак оклику в !(stringA!.isEmpty).

Я особисто віддаю перевагу дещо іншій формі:

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

У вищевикладеному твердженні відразу зрозуміло, що весь ifблок не виконується, коли є змінною nil.


0

корисно при отриманні значення від UITextField та перевірки на nil& emptyрядок

@IBOutlet weak var myTextField: UITextField!

Ось ваша функція (при натисканні на a button), яка отримує рядок від UITextField і виконує деякі інші речі

@IBAction func getStringFrom_myTextField(_ sender: Any) {

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

Це також подбає про nilцінністьempty рядок.

Це працювало для мене ідеально.


0

На мою думку, найкращий спосіб перевірити нульову та порожню рядок - це взяти підрахунок рядків.

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

Ви можете використовувати цю функцію

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

2
Не швидкий користувач; Ви можете пояснити, чому це не кидає виняток, якщо нуль передано?
— Foon

Це не кидає виняток, тому що ви взагалі не можете перейти nilв цю функцію (за винятком objc, і в цьому випадку вона справді стане збоєм).
— Альфонсо

Це не відповідає на запитання. Він не перевіряє нуль, оскільки не приймає необов'язково
— Wayne Ellery
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.