Come confrontare due stringhe ignorando il caso in linguaggio Swift?


95

Come possiamo confrontare due stringhe ignorando rapidamente il caso? per esempio:

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

Esiste un metodo che restituirà true se confrontiamo var a e var b


1
È possibile convertire entrambi in minuscolo prima di fare il confronto.
Dino Tw

8
Solo per notare che ciò lowercaseStringche è menzionato in alcune risposte fallirà in alcune lingue (Straße! = STRASSE per esempio)
Alladinian

@ Alladinian come suggeriresti di farlo allora. La maggior parte degli esempi per risolvere questo problema mostra la conversione in lettere tutte maiuscole o tutte minuscole?
Steve

5
@Steve Apple suggerisce caseInsensitiveCompare:e localizedCaseInsensitiveCompare:invece
Alladinian

3
@Steve Sure! (puoi provare "Straße".localizedCaseInsensitiveCompare("STRASSE")- Ricordati di importare Foundation)
Alladiniano

Risposte:


13

Prova questo:

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)

il risultato è il tipo di enumerazione NSComparisonResult:

enum NSComparisonResult : Int {

    case OrderedAscending
    case OrderedSame
    case OrderedDescending
}

Quindi puoi usare l'istruzione if:

if result == .OrderedSame {
    println("equal")
} else {
    println("not equal")
}

Se ricordo bene, i parametri di intervallo e locale sono opzionali e possono essere omessi del tutto.
Mick MacCallum

3
Sì, in effetti, volevo mostrare l'intero metodo con tutti i parametri.
Greg

Dovresti avere la risposta giusta qui. Confrontare le stringhe non significa solo sapere se sono uguali o meno
Mikael

181

Prova questo :

Per i più anziani Swift:

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

13
In Swift 3 devi usarea.caseInsensitiveCompare(b) == ComparisonResult.orderedSame
azhidkov

2
Nota: caseInsensitiveCompare(_:)non è incluso nella Swift Standard Library, piuttosto fa parte del Foundationframework, quindi richiede import Foundation.
chrisamanse

C'è qualche motivo per cui questo è meglio di a.lowercased() == b.lowercased()?
jowie

36

Usa il caseInsensitiveComparemetodo:

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

ComparisonResult ti dice quale parola viene prima dell'altra in ordine lessicografico (cioè quale si avvicina alla parte anteriore di un dizionario). .orderedSamesignifica che le stringhe finirebbero nello stesso punto del dizionario


cosa .orderedSamesignifica? I documenti dicono semplicemente che i due operandi sono uguali . Ma perché qui viene usata la parola "ordine"? C'è una sequenza o qualcosa del genere? E cosa fa L'operando sinistro è più piccolo dell'operando destro. ( .orderedAscending) significa per archi
Honey

1
Il risultato di @Honey Comparison ti dice quale parola viene prima dell'altra in ordine lessicografico (cioè quale si avvicina alla parte anteriore di un dizionario). .orderedSamesignifica che le stringhe finirebbero nello stesso punto del dizionario.
dasblinkenlight

1
@Honey .orderedSameè l'abbreviazione di ComparisonResult.orderSame... non è necessario nominare il tipo poiché il compilatore sa che caseInsensitiveComparerestituisce a ComparisonResult. "I due operandi sono uguali" - sono uguali in base a uno specifico ordine ... chiaramente, "Cash" e "cash" non sono valori stringa identici. "Ma perché qui si usa la parola" ordine "?" - perché è il risultato di un confronto ordinato. Gli altri valori sono orderedAscendinge orderedDescending... non è solo una questione di uguale o diverso. Quanto a "più piccolo": le stringhe sono come i numeri in una base larga.
Jim Balter

1
Sento che questo è un design API terribile. La firma non è di facile lettura ... Renderla a.caseInsensitiveCompare(b, comparing: .orderedSame)sarebbe stata più leggibile ...
Miele

25
if a.lowercaseString == b.lowercaseString {
    //Strings match
}

2
Pure Swift è la strada da percorrere qui. Non c'è bisogno di fondotinta.
Alexander - Ripristina Monica il

2
Convertire il caso e poi confrontare è sbagliato. Vedi i commenti sotto la domanda.
Jim Balter

1
@JimBalter Non direi che è "sbagliato" poiché risponde all'esempio fornito nella domanda dell'OP. Per quelli di noi che non hanno bisogno di supportare la localizzazione questo è molto più pulito!
Toddg

4
^ No, è sbagliato. Che qualcosa funzioni per un esempio è irrilevante. Questo trucco non è affatto "più pulito". La risposta accettata fornisce la soluzione corretta e pulita.
Jim Balter

8

MODO CORRETTO:

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

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

Nota: ComparisonResult.orderedSame può anche essere scritto come .orderedSame in forma abbreviata.

ALTRI MODI:

un.

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

b.

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

c.

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

7

Potrebbe semplicemente rotolare il tuo:

func equalIgnoringCase(a:String, b:String) -> Bool {
    return a.lowercaseString == b.lowercaseString
}

3
Convertire il caso e poi confrontare è sbagliato. Vedi i commenti sotto la domanda.
Jim Balter

6

localizedCaseInsensitiveContains : restituisce se il destinatario contiene una determinata stringa eseguendo una ricerca senza distinzione tra maiuscole e minuscole, che riconosce le impostazioni locali

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

Modificato :

caseInsensitiveCompare : restituisce il risultato dell'invocazione di compare (_: opzioni :) con NSCaseInsensitiveSearch come unica opzione.

if a.caseInsensitiveCompare(b) == .orderedSame {
    //returns true if a equals b (case insensitive)
}

1
La domanda riguarda il confronto, non il contenimento.
Jim Balter

Se "a contiene b" e "b contiene a" , sono uguali. Quindi questa è sicuramente una soluzione possibile, anche se potrebbe non essere la più efficace.
Philipp Maurer

1

Potresti anche scrivere tutte le lettere in maiuscolo (o minuscolo) e vedere se sono uguali.

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

Questo renderà entrambe le variabili come ”CASH”e quindi saranno uguali.

Potresti anche creare Stringun'estensione

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

if "Something ELSE".equalsIgnoreCase("something Else"){
  print("TRUE")
}

3
Convertire il caso e poi confrontare è sbagliato. Vedi i commenti sotto la domanda.
Jim Balter

1

Esempio di confronto dei numeri di telefono; utilizzando 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")
}

0

Swift 4, ho seguito il percorso di estensione String utilizzando caseInsensitiveCompare () come modello (ma consentendo all'operando di essere un opzionale). Ecco il parco giochi che ho usato per metterlo insieme (nuovo per Swift, quindi feedback più che benvenuto).

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

2
Puoi semplicemente usare .orderedSamepiuttosto che ComparisonResult.orderedSame.
Jim Balter

0

Puoi semplicemente scrivere la tua estensione stringa per il confronto in poche righe di codice

extension String {

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

0

Per Swift 5 Ignorare il caso e confrontare due stringhe

var a = "cash"
var b = "Cash"
if(a.caseInsensitiveCompare(b) == .orderedSame){
     print("Ok")
}

-1

Swift 3

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

}

2
Questo è sbagliato. Vedi i commenti sotto la domanda.
Jim Balter

-1

Swift 3 : puoi definire il tuo operatore, ad es ~=.

infix operator ~=

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

Che poi puoi provare in un parco giochi

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

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

test() // prints 'same'

Non l'ho sottovalutato, ma nota che questa è generalmente una pessima idea, poiché l'operatore di corrispondenza del modello personalizzato sopra avrà la precedenza sul confronto del modello nativo solitamente utilizzato quando si abbinano le Stringistanze tra loro (o ad altri Stringletterali). Immaginate let str = "isCAMELcase"di essere commutato, con un caso come segue: case "IsCamelCase": ... . Con il metodo sopra, questo caseverrebbe inserito con successo, cosa non prevista dall'implementazione del Stringpattern matching nelle librerie standard . Una risposta Swift 3 aggiornata è ancora buona, ma ...
dfri

... considera l'utilizzo di una funzione personalizzata (o Stringestensione) come supporto sopra invece di sovrascrivere la Stringcorrispondenza del modello predefinita .
venerdì

-1
extension String
{
    func equalIgnoreCase(_ compare:String) -> Bool
    {
        return self.uppercased() == compare.uppercased()
    }
}

campione di utilizzo

print("lala".equalIgnoreCase("LALA"))
print("l4la".equalIgnoreCase("LALA"))
print("laLa".equalIgnoreCase("LALA"))
print("LALa".equalIgnoreCase("LALA"))

1
Questo non funziona per alcune stringhe in alcune lingue ... vedi i commenti sotto la domanda, e le tante risposte corrette, alcune delle quali - compresa quella accettata - hanno preceduto il tuo di anni.
Jim Balter

-2

Swift 3:

È inoltre possibile utilizzare il confronto localizzato senza distinzione tra maiuscole e minuscole tra due funzioni di stringhe e restituisce Bool

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

if a.localizedCaseInsensitiveContains(b) {
    print("Identical")           
} else {
    print("Non Identical")
}

2
La tua soluzione non è corretta. Considera le stringhe "casha" e "Cash"
clarkcox3
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.