Como comparar duas strings ignorando maiúsculas e minúsculas na linguagem Swift?

93

Como podemos comparar duas cordas ignorando maiúsculas e minúsculas? por exemplo:

var a = "Cash"
var b = "cash"

Existe algum método que retornará verdadeiro se compararmos var a & var b

ak_tyagi
fonte
1
Você pode converter ambos para minúsculas antes de fazer a comparação.
Dino Tw
8
Apenas para observar que lowercaseStringisso é mencionado em algumas respostas falhará em alguns idiomas (Straße! = STRASSE por exemplo)
Alladinian
@Alladinian como você sugere fazer isso então. A maioria dos exemplos para resolver esse problema mostra a conversão para todas as letras maiúsculas ou todas as minúsculas?
Steve
5
@Steve Apple sugere caseInsensitiveCompare:e em localizedCaseInsensitiveCompare:vez disso
Alladinian
3
@Steve Sure! (você pode tentar "Straße".localizedCaseInsensitiveCompare("STRASSE")- Lembre-se de importar Foundation)
Alladinian

Respostas:

13

Experimente isto:

var a = "Cash"
var b = "cash"
let result: NSComparisonResult = a.compare(b, options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil, locale: nil)

// You can also ignore last two parameters(thanks 0x7fffffff)
//let result: NSComparisonResult = a.compare(b, options: NSStringCompareOptions.CaseInsensitiveSearch)

o resultado é um tipo de enum NSComparisonResult:

enum NSComparisonResult : Int {

    case OrderedAscending
    case OrderedSame
    case OrderedDescending
}

Portanto, você pode usar a instrução if:

if result == .OrderedSame {
    println("equal")
} else {
    println("not equal")
}
Greg
fonte
Se bem me lembro, os parâmetros de intervalo e local são opcionais e podem ser totalmente omitidos.
Mick MacCallum
3
Sim, queria mostrar o método completo com todos os parâmetros.
Greg
Você deve ter a resposta certa aqui. Comparar strings não é apenas saber se elas são iguais ou não
Mikael
181

Experimente isto:

Para o Swift mais antigo:

var a : String = "Cash"
var b : String = "cash"

if(a.caseInsensitiveCompare(b) == NSComparisonResult.OrderedSame){
    println("voila")
}

Swift 3+

var a : String = "Cash"
var b : String = "cash"

if(a.caseInsensitiveCompare(b) == .orderedSame){
    print("voila")
}
iAnurag
fonte
13
Em Swift 3, você precisa usara.caseInsensitiveCompare(b) == ComparisonResult.orderedSame
azhidkov
2
Nota: caseInsensitiveCompare(_:)não está incluso na Biblioteca Padrão Swift, ao invés disso, faz parte da Foundationestrutura, portanto, obrigando import Foundation.
chrisamanse
36

caseInsensitiveCompareMétodo de uso :

let a = "Cash"
let b = "cash"
let c = a.caseInsensitiveCompare(b) == .orderedSame
print(c) // "true"

ComparisonResult informa qual palavra vem antes da outra em ordem lexicográfica (ou seja, qual palavra vem mais perto do início de um dicionário). .orderedSamesignifica que as strings iriam parar no mesmo lugar no dicionário

dasblinkenlight
fonte
o que .orderedSamesignifica Os documentos apenas dizem que os dois operandos são iguais . Mas por que a palavra 'ordem' é usada aqui? Existe uma sequência ou algo assim? E o que faz O operando esquerdo é menor que o operando direito. ( .orderedAscending) média para strings
Honey
1
O resultado da comparação @Honey informa qual palavra vem antes da outra em ordem lexicográfica (ou seja, qual palavra vem mais perto do início de um dicionário). .orderedSamesignifica que as strings terminariam no mesmo lugar no dicionário.
dasblinkenlight
1
@Honey .orderedSameé a abreviação de ComparisonResult.orderSame... você não precisa nomear o tipo, pois o compilador sabe que caseInsensitiveCompareretorna um ComparisonResult. "Os dois operandos são iguais" - eles são iguais de acordo com uma ordem específica ... claramente, "Dinheiro" e "dinheiro" não são valores de string idênticos. "Mas por que a palavra 'ordem' é usada aqui?" - porque é o resultado de uma comparação ordenada. Os outros valores são orderedAscendinge orderedDescending... não é apenas uma questão de igual ou diferente. Quanto a "menor": as strings são como números em uma base grande.
Jim Balter,
1
Eu sinto que este é um péssimo design de API. A assinatura não é fácil de ler ... Torná-la a.caseInsensitiveCompare(b, comparing: .orderedSame)teria sido mais legível ...
Honey,
25
if a.lowercaseString == b.lowercaseString {
    //Strings match
}
Steve
fonte
2
Pure Swift é o caminho a percorrer aqui. Não há necessidade de fundação.
Alexander - Reintegrar Monica
2
Converter o caso e depois comparar está errado. Veja os comentários na pergunta.
Jim Balter
1
@JimBalter Eu não diria que está "errado", pois responde ao exemplo dado na pergunta do OP. Para aqueles de nós que não precisam de suporte à localização, isso é muito mais limpo!
toddg
4
^ Não, está errado. Que algo aconteça para funcionar para um exemplo é irrelevante. Este hack não é "mais limpo" de forma alguma. A resposta aceita fornece a solução correta e limpa.
Jim Balter
7

Poderia apenas rolar o seu próprio:

func equalIgnoringCase(a:String, b:String) -> Bool {
    return a.lowercaseString == b.lowercaseString
}
mate
fonte
3
Converter o caso e depois comparar está errado. Veja os comentários na pergunta.
Jim Balter
6

MANEIRA CORRETA:

let a: String = "Cash"
let b: String = "cash"

if a.caseInsensitiveCompare(b) == .orderedSame {
    //Strings match 
}

Observação: ComparisonResult.orderedSame também pode ser escrito como .orderedSame abreviadamente.

OUTRAS MANEIRAS:

uma.

if a.lowercased() == b.lowercased() {
    //Strings match 
}

b.

if a.uppercased() == b.uppercased() {
    //Strings match 
}

c.

if a.capitalized() == b.capitalized() {
    //Strings match 
}
Saurabh Bhatia
fonte
6

localizedCaseInsensitiveContains : retorna se o receptor contém uma determinada string executando uma pesquisa que não diferencia maiúsculas de minúsculas e reconhece a localidade

if a.localizedCaseInsensitiveContains(b) {
    //returns true if a contains b (case insensitive)
}

Editado :

caseInsensitiveCompare : Retorna o resultado de chamar compare (_: options :) com NSCaseInsensitiveSearch como a única opção.

if a.caseInsensitiveCompare(b) == .orderedSame {
    //returns true if a equals b (case insensitive)
}
cgeek
fonte
1
A questão é sobre comparação, não contenção.
Jim Balter,
Se "a contém b" e "b contém a" , eles são iguais. Portanto, esta é certamente uma solução possível, mesmo que não seja a mais eficaz.
Philipp Maurer,
1

Você também pode colocar todas as letras em maiúsculas (ou minúsculas) e ver se elas são iguais.

var a =Cashvar b =CAShif a.uppercaseString == b.uppercaseString{
  //DO SOMETHING
}

Isso fará com que ambas as variáveis ”CASH”sejam iguais.

Você também pode fazer uma Stringextensão

extension String{
  func equalsIgnoreCase(string:String) -> Bool{
    return self.uppercaseString == string.uppercaseString
  }
}

if "Something ELSE".equalsIgnoreCase("something Else"){
  print("TRUE")
}
milo526
fonte
3
Converter o caso e depois comparar está errado. Veja os comentários na pergunta.
Jim Balter
1

Exemplo de comparação de números de telefone; usando o Swift 4.2

var selectPhone = [String]()

if selectPhone.index(where: {$0.caseInsensitiveCompare(contactsList[indexPath.row].phone!) == .orderedSame}) != nil {
    print("Same value")
} else {
    print("Not the same")
}
ikbal
fonte
0

Swift 4, usei a rota de extensão String usando caseInsensitiveCompare () como um modelo (mas permitindo que o operando seja opcional). Aqui está o playground que eu costumava montar (novo no Swift, então, o feedback é mais do que bem-vindo).

import UIKit

extension String {
    func caseInsensitiveEquals<T>(_ otherString: T?) -> Bool where T : StringProtocol {
        guard let otherString = otherString else {
            return false
        }
        return self.caseInsensitiveCompare(otherString) == ComparisonResult.orderedSame
    }
}

"string 1".caseInsensitiveEquals("string 2") // false

"thingy".caseInsensitiveEquals("thingy") // true

let nilString1: String? = nil
"woohoo".caseInsensitiveEquals(nilString1) // false
William T. Mallard
fonte
2
Você pode apenas usar em .orderedSamevez de ComparisonResult.orderedSame.
Jim Balter,
0

Você pode simplesmente escrever sua extensão de string para comparação em apenas algumas linhas de código

extension String {

    func compare(_ with : String)->Bool{
        return self.caseInsensitiveCompare(with) == .orderedSame
    } 
}
Mujahid Latif
fonte
0

Para Swift 5 Ignorar o caso e comparar duas cordas

var a = "cash"
var b = "Cash"
if(a.caseInsensitiveCompare(b) == .orderedSame){
     print("Ok")
}
M Murteza
fonte
-1

Swift 3

if a.lowercased() == b.lowercased() {

}
DoubleK
fonte
2
Isto está errado. Veja os comentários na pergunta.
Jim Balter
-1

Swift 3 : Você pode definir sua própria operadora, por exemplo ~=.

infix operator ~=

func ~=(lhs: String, rhs: String) -> Bool {
   return lhs.caseInsensitiveCompare(rhs) == .orderedSame
}

Que você pode tentar em um playground

let low = "hej"
let up = "Hej"

func test() {
    if low ~= up {
        print("same")
    } else {
        print("not same")
    }
}

test() // prints 'same'
Sajjon
fonte
Eu não votei contra isso, mas observe que isso geralmente é uma ideia muito ruim, já que o operador de correspondência de padrão personalizado acima terá precedência sobre a correspondência de padrão nativo geralmente usada ao combinar Stringinstâncias entre si (ou com outros Stringliterais). Imagine que let str = "isCAMELcase"está sendo comutada, com um caso como segue: case "IsCamelCase": ... . Com o método acima, isso caseseria inserido com sucesso, o que não é esperado vindo da implementação de libs Stringpadrão de correspondência de padrões. Uma resposta atualizada do Swift 3 ainda é boa, mas ...
dfri
... considere usar uma função personalizada (ou Stringextensão) como auxiliar acima, em vez de substituir a Stringcorrespondência de padrão padrão.
dfri
-1
extension String
{
    func equalIgnoreCase(_ compare:String) -> Bool
    {
        return self.uppercased() == compare.uppercased()
    }
}

amostra de uso

print("lala".equalIgnoreCase("LALA"))
print("l4la".equalIgnoreCase("LALA"))
print("laLa".equalIgnoreCase("LALA"))
print("LALa".equalIgnoreCase("LALA"))
luhuiya
fonte
1
Isso não funciona para algumas strings em alguns idiomas ... veja os comentários sob a pergunta e as muitas respostas corretas, algumas das quais - incluindo a aceita - precedem as suas por anos.
Jim Balter,
-2

Swift 3:

Você também pode usar a comparação localizada sem distinção entre maiúsculas e minúsculas entre a função de duas strings e ela retorna Bool

var a = "cash"
var b = "Cash"

if a.localizedCaseInsensitiveContains(b) {
    print("Identical")           
} else {
    print("Non Identical")
}
Kegham K.
fonte
2
Sua solução está incorreta. Considere as strings "casha" e "Cash"
clarkcox3