Verificar se há nula e vazia

134

Existe uma maneira de verificar seqüências de caracteres para nile ""no Swift? No Rails, eu posso usar blank()para verificar.

Atualmente, tenho isso, mas parece um exagero:

    if stringA? != nil {
        if !stringA!.isEmpty {
            ...blah blah
        }
    }
reitor
fonte
1
(@sutra e @ imanou-petit) são melhores.
Sr. Ming

Respostas:

211

Se você está lidando com Strings opcionais, isso funciona:

(string ?? "").isEmpty

O ??operador coalescente nulo retorna o lado esquerdo se não for nulo; caso contrário, retorna o lado direito.

Você também pode usá-lo assim para retornar um valor padrão:

(string ?? "").isEmpty ? "Default" : string!
jrc
fonte
3
Elegante ??? Você basicamente escreveu "se a string não é mais nula e a chamada está vazia
nela
73

Talvez você possa usar a cláusula 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 */
}
Ryan
fonte
2
Não funciona com o Swift 2, obtendo esse erro de tempo de execução, fatal error: unexpectedly found nil while unwrapping an Optional valuemas minha constante stringpossui dados de sequência.
Nagendra Rao
3
Isso funciona no Swift 3:if let string = string, !string.isEmpty { /* string is not blank */ }
EricS 7/16/16
1
@AmrLotfy guard leté uma alternativa se você quiser encerrar o fluxo de controle abaixo da instrução. No entanto nada está sendo desembrulhou na cláusula where aqui (o é uma negação booleana!)
Ryan
assim como sobre este str .isEmpty em vez de string = cadeia onde string.isEmpty!?!
Pankaj
28

Se você estiver usando o Swift 2, aqui está um exemplo que meu colega sugeriu, que adiciona a propriedade isNilOrEmpty nas Strings opcionais:

protocol OptionalString {}
extension String: OptionalString {}

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

Você pode usar isNilOrEmpty na própria sequência opcional

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

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

    let someText:String? = "lorem"
    XCTAssertFalse(someText.isNilOrEmpty)
}
Ken Ko
fonte
Você pode esclarecer o que fez aqui ou algum recurso que possa explicar isso em detalhes. Como por que OptionalString é declarado? Eu não estou recebendo a sintaxe. Não é como a implementação normal de extensões. Muito obrigado antecipadamente
Vinayak Parmar
@VinayakParmar OptionalString é declarado aqui porque where Wrapped:deve especificar um protocolo e não um tipo.
Adam Johns
Talvez você poderia nomear isNilOrEmptya hasValue(ou algo parecido) e inverter a lógica
Islam Q.
28

Usando a guarddeclaração

Eu estava usando Swift por um tempo antes de aprender sobre a guarddeclaração. Agora eu sou um grande fã. É usado de forma semelhante à ifdeclaração, mas permite retorno antecipado e apenas cria um código muito mais limpo em geral.

Para usar guarda ao verificar para garantir que uma sequência não seja nula nem vazia, você pode fazer o seguinte:

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)

Isso desembrulha a cadeia opcional e verifica se ela não está vazia de uma só vez. Se for nulo (ou vazio), você retornará da sua função (ou loop) imediatamente e tudo depois que ela for ignorada. Mas se a declaração de guarda for aprovada, você poderá usar com segurança sua corda não embrulhada.

Veja também

Suragch
fonte
seja cuidadoso. print (myString) não será executado, se String for nulo ou vazio, porque o protetor foi projetado para não cair depois da fase de entrada.
precisa
@KangByul, está correto e é a intenção da lógica aqui. Presumivelmente, se a string estiver nilvazia ou não, não se deseja chamar print(myString). Se você precisasse continuar a execução após um nilou vazio String, usaria em if letvez de guard.
Suragch 15/02
Obrigado por um elogio. Eu sei, apenas digo a outros que não sabem muito sobre guarda.
precisa
4
@KangByul Eu não entendo o ponto do seu comentário "tenha cuidado", acho que isso afugenta as pessoas de uma ótima solução, a declaração de retorno está claramente correta na declaração de outra pessoa, acho que você deve excluir seu comentário
Brian Ogden
16

Com o Swift 5, você pode implementar uma Optionalextensão para o Stringtipo com uma propriedade booleana que retorna se uma sequência opcional não tiver valor ou estiver vazia:

extension Optional where Wrapped == String {

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

}

No entanto, Stringimplementa a isEmptypropriedade conforme o protocolo Collection. Portanto, podemos substituir restrição genérica do código anterior ( Wrapped == String) com um mais amplo ( Wrapped: Collection) para que Array, Dictionarye Settambém beneficiar o nosso novo isNilOrEmptyimóvel:

extension Optional where Wrapped: Collection {

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

}

Uso com 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

Uso com 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

Fontes:

Imanou Petit
fonte
1
I como este, o único ajustar gostaria de fazer é mudar o nome isNilOrEmptyda isEmptyOrNilpara coincidir com o prefixo por isso é facilmente encontrável via o mesmo padrão para preenchimento automático. Percebi mais adoção dessa extensão por parte dos colegas com quem trabalho, apenas por encontrá-la dessa maneira.
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
fonte
1
Elegante mas desajeitado;), a "verdadeira" lança um bocado fora do intution
TruMan1
9

Eu sei que existem muitas respostas para essa pergunta, mas nenhuma delas parece ser tão conveniente quanto esta (na minha opinião) para validar UITextFielddados, que é um dos casos mais comuns de uso:

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

Você pode apenas usar

textField.text.isNilOrEmpty

Você também pode pular a opção .trimmingCharacters(in:.whitespaces)se não considerar espaços em branco como uma sequência vazia ou usá-la para testes de entrada mais complexos, como

var isValidInput: Bool {
    return !isNilOrEmpty && self!.trimmingCharacters(in: .whitespaces).characters.count >= MIN_CHARS
}
Sir Codesalot
fonte
Ótima resposta, o Op não precisou se os espaços em branco eram contados em branco, então aqui está minha versão: public extension Opcional em que Wrapped == String {var isEmptyOrNil: Bool {return (self ?? "") .isEmpty}}
sachadso
7

Eu recomendaria.

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

mapaplica-se o argumento da função se o opcional é .Some.
A captura do playground também mostra outra possibilidade com o novo Swift 1.2, se for permitido o encadernação.

insira a descrição da imagem aqui

Preço Ringo
fonte
7

Se você deseja acessar a string como não opcional, use a resposta de Ryan , mas se você se importa apenas com o não vazio da string, minha abreviação preferida para isso é

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

Como ==funciona bem com booleanos opcionais, acho que isso deixa o código legível sem obscurecer a intenção original.

Se você quiser verificar o oposto: se a string for nilor "", eu prefiro verificar os dois casos explicitamente para mostrar a intenção correta:

if stringA == nil || stringA?.isEmpty == true {
    ...blah blah
}
Alex Pretzlav
fonte
@ TruMan1 está correto, o objetivo do primeiro exemplo é verificar se a string não está vazia.
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
    }
}

Use assim na sequência opcional:

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

Swift 3 Para verificar a melhor maneira de String vazia

if !string.isEmpty{

// do stuff

}
Anas
fonte
2

Você pode criar sua própria função personalizada, se isso é algo que você espera fazer muito.

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
fonte
2

Solução Swift 3 Use o valor desembrulhado opcional e verifique com o booleano.

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

Usando isEmpty

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

Usando allSatisfy

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

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

Usando String opcional

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

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

Referência: https://useyourloaf.com/blog/empty-strings-in-swift/

raaz
fonte
1

Crie uma extensão 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

Observe que isso retornará TRUE se a string contiver um ou mais espaços em branco. Para tratar a string em branco como "vazia", ​​use ...

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

... em vez de. Isso requer fundação.

Use-o assim ...

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

Swift 3 Isso funciona bem para verificar se a string está realmente vazia. Porque isEmpty retorna true quando há um espaço em branco.

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

Exemplos:

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

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

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

Você deve fazer algo assim:
if !(string?.isEmpty ?? true) { //Not nil nor empty }

O operador coalescente nulo verifica se o opcional não é nulo; caso contrário, verifica sua propriedade; nesse caso, é Vazio. Como esse opcional pode ser nulo, você fornece um valor padrão que será usado quando o opcional for nulo.

Dominik Babić
fonte
1

Esta é uma solução geral para todos os tipos que estão em conformidade com o Collectionprotocolo, que inclui String:

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

Ao lidar com a passagem de valores do banco de dados local para o servidor e vice-versa, eu estava tendo muitos problemas com? E! E se não.

Então, eu criei um utilitário Swift3.0 para lidar com casos nulos e quase totalmente posso evitar? E! No código.

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

Ex:-

Antes :

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

Depois de :

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

e quando for necessário verificar uma sequência válida,

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

Isso me salvou de ter que lidar com o problema de adicionar e remover vários 's' e! 'S depois de escrever um código que fazia sentido.

Nikhil Mathew
fonte
0

Use o operador ternário (também conhecido como operador condicional C++ forever!):

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

O stringA!desembrulhamento forçado acontece apenas quando stringA != nil, portanto, é seguro. A == falseverbosidade é um pouco mais legível do que outro ponto de exclamação !(stringA!.isEmpty).

Pessoalmente, prefiro uma forma ligeiramente diferente:

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

Na declaração acima, é imediatamente muito claro que o ifbloco inteiro não é executado quando uma variável é nil.

Gary
fonte
0

útil ao obter valor de UITextField e verificar nil& emptystring

@IBOutlet weak var myTextField: UITextField!

Heres sua função (quando você toca em um button) que obtém a string do UITextField e faz outras coisas

@IBAction func getStringFrom_myTextField(_ sender: Any) {

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

Isso cuidará do nilvalor e também da emptystring.

Funcionou perfeitamente bem para mim.

Soropromo
fonte
0

Na minha opinião, a melhor maneira de verificar a cadeia nula e vazia é fazer a contagem de cadeias.

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
fonte
-4

você pode usar esta função

 class func stringIsNilOrEmpty(aString: String) -> Bool { return (aString).isEmpty }
Ahmed Khemiri
fonte
2
Não é um usuário rápido; você poderia explicar por que isso não gera uma exceção se nada for passado?
Foon
Não gera uma exceção porque você não pode passar nilpara essa função (exceto objc; nesse caso, ela realmente trava).
Alfonso
Isso não responde à pergunta. Ele não verifica para nil, uma vez que não aceita um opcional
Wayne Ellery