Проверить строку на ноль и пусто

134

Есть ли способ проверить строки для Swift nilи ""в нем? В Rails я могу использовать blank()для проверки.

Сейчас у меня есть это, но кажется излишним:

    if stringA? != nil {
        if !stringA!.isEmpty {
            ...blah blah
        }
    }
декан
источник
1
(@sutra и @ imanou-petit) ответы лучше.
Мистер Мин,

Ответы:

212

Если вы имеете дело с необязательными строками, это работает:

(string ?? "").isEmpty

??Оператор ноль сливающихся возвращает левую сторону , если это не-ноль, в противном случае она возвращает правую сторону.

Вы также можете использовать его так, чтобы вернуть значение по умолчанию:

(string ?? "").isEmpty ? "Default" : string!
JRC
источник
3
Элегантный ??? По сути, вы написали: «Если строка не равна нулю, иначе - пустая строка и этот вызов на ней пуст ... Какое логическое утверждение.
Ренетик
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имеет строковые данные.
Нагендра Рао
3
Это работает в Swift 3:if let string = string, !string.isEmpty { /* string is not blank */ }
EricS
1
@AmrLotfy guard let- альтернатива, если вы хотите завершить поток управления под оператором. Однако здесь ничего не разворачивается в предложении where (! - это логическое отрицание)
Райан
так как насчет этого! str? .isEmpty вместо string = string, где! 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)

Это разворачивает необязательную строку и сразу проверяет, не пуста ли она. Если оно равно нулю (или пусто), вы немедленно возвращаетесь из своей функции (или цикла), и все, что находится после него, игнорируется. Но если оператор защиты проходит, вы можете безопасно использовать развернутую строку.

Смотрите также

Suragch
источник
быть осторожен. print (myString) не будет работать, если String имеет значение nil или пусто, потому что охранник разработан, чтобы не упасть после перехода в фазу else.
Кан
@KangByul, это правильно, и это смысл логики здесь. Предположительно, если строка nilпуста или пуста, звонить не нужно print(myString). Если вам нужно продолжить выполнение после a nilили empty String, вы должны использовать if letвместо guard.
Suragch
Спасибо за похвалу. Я знаю, я просто говорю тем, кто мало что знает о страже.
Кан
4
@KangByul Я не понимаю смысл вашего комментария «будьте осторожны», я думаю, что это отпугивает людей от отличного решения, выражение return явно правильно в заявлении guard else, я думаю, вам следует удалить свой комментарий
Брайан Огден
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

Источники:

Imanou Petit
источник
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 не уточнил, считаются ли пробелы пустыми, поэтому вот моя версия: public extension Optional where 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 правильно, цель первого примера - проверить, не пуста ли строка .
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
    }
}

Используйте это в необязательной строке:

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")
}
vol7ron
источник
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/

Raaz
источник
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

Обратите внимание, что это вернет ИСТИНА, если строка содержит один или несколько пробелов. Чтобы рассматривать пустую строку как «пустую», используйте ...

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

... вместо этого. Для этого требуется Foundation.

Используйте это так ...

if String.isNilOrEmpty("hello world") == true 
{   print("it's a string!")
}
JustPixelz
источник
1

Swift 3 Это хорошо работает, чтобы проверить, действительно ли строка пуста. Потому что isEmpty возвращает true, когда есть пробел.

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
FredFlinstone
источник
1

Вы должны сделать что-то вроде этого:
if !(string?.isEmpty ?? true) { //Not nil nor empty }

Оператор объединения Nil проверяет, не является ли параметр nil, если он не равен nil, затем проверяет его свойство, в данном случае isEmpty. Поскольку этот необязательный параметр может иметь значение nil, вы указываете значение по умолчанию, которое будет использоваться, когда значение параметра optional равно nil.

Доминик Бабич
источник
1

Это общее решение для всех типов, соответствующих Collectionпротоколу, которое включает String:

extension Optional where Wrapped: Collection {
    var isNilOrEmpty: Bool {
        self?.isEmpty ?? true
    }
}
Даниил
источник
0

Когда я имел дело с передачей значений из локальной базы данных на сервер и наоборот, у меня было слишком много проблем с? И! И с чем нет.

Итак, я создал утилиту 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.

Gary
источник
0

полезно при получении значения из UITextField и проверке nil& emptystring

@IBOutlet weak var myTextField: UITextField!

Вот ваша функция (когда вы нажимаете на 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строке.

У меня это сработало отлично.

Soropromo
источник
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")
}
yo2bh
источник
-4

вы можете использовать эту функцию

 class func stringIsNilOrEmpty(aString: String) -> Bool { return (aString).isEmpty }
Ахмед Хемири
источник
2
Не быстрый пользователь; не могли бы вы объяснить, почему это не вызывает исключение, если передается nil?
Foon
Он не генерирует исключение, потому что вы вообще не можете перейти nilв эту функцию (кроме objc, и в этом случае она действительно выйдет из строя).
Альфонсо
Это не отвечает на вопрос. Он не проверяет ноль, так как не принимает необязательные
Уэйн Эллери