Wie vergleiche ich zwei Zeichenfolgen, wobei die Groß- und Kleinschreibung in der Swift-Sprache ignoriert wird?

93

Wie können wir zwei Zeichenfolgen in einem schnell ignorierenden Fall vergleichen? für zB:

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

Gibt es eine Methode, die true zurückgibt, wenn wir var a & var b vergleichen?

ak_tyagi
quelle
1
Sie können beide vor dem Vergleich in Kleinbuchstaben umwandeln.
Dino Tw
8
Nur um zu beachten, lowercaseStringdass das in einigen Antworten erwähnt wird, wird in einigen Sprachen fehlschlagen (Straße! = STRASSE zum Beispiel)
Alladinian
@ Alladinian, wie würden Sie vorschlagen, es dann zu tun. Die meisten Beispiele zur Lösung dieses Problems zeigen, dass entweder in Groß- oder Kleinbuchstaben konvertiert wird.
Steve
5
@ Steve Apple schlägt vor caseInsensitiveCompare:& localizedCaseInsensitiveCompare:stattdessen
Alladinian
3
@Steve Sicher! (Sie können versuchen "Straße".localizedCaseInsensitiveCompare("STRASSE")- Denken Sie daran zu importieren Foundation)
Alladinian

Antworten:

13

Versuche dies:

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)

Ergebnis ist der Typ der NSComparisonResult-Aufzählung:

enum NSComparisonResult : Int {

    case OrderedAscending
    case OrderedSame
    case OrderedDescending
}

Sie können also die if-Anweisung verwenden:

if result == .OrderedSame {
    println("equal")
} else {
    println("not equal")
}
Greg
quelle
Wenn ich mich richtig erinnere, sind die Bereichs- und Gebietsschemaparameter optional und können vollständig weggelassen werden.
Mick MacCallum
3
Ja, ich wollte die ganze Methode mit allen Parametern zeigen.
Greg
Sie sollten hier die richtige Antwort haben. Beim Vergleichen von Zeichenfolgen geht es nicht nur darum zu wissen, ob sie gleich sind oder nicht
Mikael,
181

Versuche dies :

Für ältere schnelle:

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
quelle
13
In Swift 3 müssen Sie verwendena.caseInsensitiveCompare(b) == ComparisonResult.orderedSame
Azhidkov
2
Hinweis: caseInsensitiveCompare(_:)ist nicht in der Swift Standard Library enthalten, sondern Teil des FoundationFrameworks und erfordert daher import Foundation.
Chrisamanse
36

Verwendung caseInsensitiveCompareMethode:

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

ComparisonResult gibt an, welches Wort in lexikografischer Reihenfolge früher als das andere kommt (dh welches näher an die Vorderseite eines Wörterbuchs kommt). .orderedSamebedeutet, dass die Zeichenfolgen an derselben Stelle im Wörterbuch landen würden

dasblinkenlight
quelle
was tut .orderedSamebedeuten? Die Dokumente sagen nur, dass die beiden Operanden gleich sind . Aber warum wird hier das Wort "Ordnung" verwendet? Gibt es eine Sequenz oder so? Und was macht der linke Operand ist kleiner als der rechte Operand. ( .orderedAscending) Mittelwert für Strings
Honey
1
Das @ Honey-Vergleichsergebnis gibt an, welches Wort in lexikografischer Reihenfolge früher als das andere kommt (dh welches näher an die Vorderseite eines Wörterbuchs kommt). .orderedSamebedeutet, dass die Zeichenfolgen an derselben Stelle im Wörterbuch landen würden.
Dasblinkenlight
1
@Honey .orderedSameist die Abkürzung für ComparisonResult.orderSame... Sie müssen den Typ nicht benennen, da der Compiler weiß, dass caseInsensitiveComparea zurückgegeben wird ComparisonResult. "Die beiden Operanden sind gleich" - sie sind in einer bestimmten Reihenfolge gleich ... klar, "Cash" und "Cash" sind keine identischen Zeichenfolgenwerte. "Aber warum wird hier das Wort 'Ordnung' verwendet?" - weil es das Ergebnis eines geordneten Vergleichs ist. Die anderen Werte sind orderedAscendingund orderedDescending... es ist nicht nur eine Frage von gleich oder verschieden. Was "kleiner" betrifft: Zeichenfolgen sind wie Zahlen in einer großen Basis.
Jim Balter
1
Ich denke, das ist ein schreckliches API-Design. Die Unterschrift ist nicht leicht zu lesen ... Es a.caseInsensitiveCompare(b, comparing: .orderedSame)wäre besser lesbar gewesen ...
Honey
25
if a.lowercaseString == b.lowercaseString {
    //Strings match
}
Steve
quelle
2
Pure Swift ist der richtige Weg hierher. Keine Notwendigkeit für eine Gründung.
Alexander - Reinstate Monica
2
Fall konvertieren und dann vergleichen ist falsch. Siehe die Kommentare unter der Frage.
Jim Balter
1
@ JimBalter Ich würde nicht sagen, dass es "falsch" ist, da es das Beispiel in der Frage des OP beantwortet. Für diejenigen von uns, die die Lokalisierung nicht unterstützen müssen, ist dies viel sauberer!
Toddg
4
^ Nein, es ist falsch. Dass für ein Beispiel etwas funktioniert, ist irrelevant. Dieser Hack ist überhaupt nicht "sauberer". Die akzeptierte Antwort gibt die richtige, saubere Lösung.
Jim Balter
7

Könnte einfach dein eigenes rollen:

func equalIgnoringCase(a:String, b:String) -> Bool {
    return a.lowercaseString == b.lowercaseString
}
matt
quelle
3
Fall konvertieren und dann vergleichen ist falsch. Siehe die Kommentare unter der Frage.
Jim Balter
6

DER RICHTIGE WEG:

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

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

Bitte beachten Sie: ComparisonResult.orderedSame kann auch in Kurzform als .orderedSame geschrieben werden.

ANDERE MÖGLICHKEITEN:

ein.

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
quelle
6

localizedCaseInsensitiveContains : Gibt zurück, ob der Empfänger eine bestimmte Zeichenfolge enthält, indem eine Suche ohne Berücksichtigung der Groß- und Kleinschreibung durchgeführt wird

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

Bearbeitet :

caseInsensitiveCompare : Gibt das Ergebnis des Aufrufs von compare (_: options :) mit NSCaseInsensitiveSearch als einziger Option zurück.

if a.caseInsensitiveCompare(b) == .orderedSame {
    //returns true if a equals b (case insensitive)
}
cgeek
quelle
1
Die Frage betrifft den Vergleich, nicht die Eindämmung.
Jim Balter
Wenn "a b enthält" und "b a enthält" , sind sie gleich. Dies ist sicherlich eine mögliche Lösung, auch wenn sie möglicherweise nicht die effektivste ist.
Philipp Maurer
1

Sie können auch alle Buchstaben in Groß- oder Kleinbuchstaben schreiben und prüfen, ob sie identisch sind.

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

Dadurch werden beide Variablen als ”CASH” und somit gleich.

Sie können auch eine StringErweiterung vornehmen

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

if "Something ELSE".equalsIgnoreCase("something Else"){
  print("TRUE")
}
milo526
quelle
3
Fall konvertieren und dann vergleichen ist falsch. Siehe die Kommentare unter der Frage.
Jim Balter
1

Beispiel für den Vergleich von Telefonnummern; mit 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
quelle
0

Swift 4, ich bin die String-Erweiterungsroute mit caseInsensitiveCompare () als Vorlage gegangen (wobei der Operand optional sein konnte). Hier ist der Spielplatz, auf dem ich ihn zusammengestellt habe (neu bei Swift, daher Feedback mehr als willkommen).

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
quelle
2
Sie können nur verwenden, .orderedSameanstatt ComparisonResult.orderedSame.
Jim Balter
0

Sie können Ihre String-Erweiterung zum Vergleich einfach in nur wenigen Codezeilen schreiben

extension String {

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

Für Swift 5 Ignorieren Sie den Fall und vergleichen Sie zwei Zeichenfolgen

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

Swift 3

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

}
DoubleK
quelle
2
Das ist falsch. Siehe die Kommentare unter der Frage.
Jim Balter
-1

Swift 3 : Sie können Ihren eigenen Operator definieren, z ~=.

infix operator ~=

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

Was Sie dann auf einem Spielplatz ausprobieren können

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

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

test() // prints 'same'
Sajjon
quelle
Ich habe dies nicht abgelehnt, aber beachten Sie, dass dies im Allgemeinen eine ziemlich schlechte Idee ist, da der oben beschriebene benutzerdefinierte Mustervergleichsoperator Vorrang vor dem nativen Mustervergleich hat, der normalerweise beim Abgleichen von StringInstanzen untereinander (oder mit anderen StringLiteralen) verwendet wird. Stellen Sie let str = "isCAMELcase"sich vor, Sie werden mit einem Fall wie folgt umgeschaltet : case "IsCamelCase": ... . Mit der obigen Methode casewürde dies erfolgreich eingegeben, was nicht von der Standard-libs-Implementierung des StringMustervergleichs erwartet wird . Eine aktualisierte Swift 3 Antwort ist zwar immer noch gut, aber ...
dfri
... sollten Sie eine benutzerdefinierte Funktion (oder StringErweiterung) als Hilfsmittel verwenden, anstatt den Standardmusterabgleich zu überschreiben String.
dfri
-1
extension String
{
    func equalIgnoreCase(_ compare:String) -> Bool
    {
        return self.uppercased() == compare.uppercased()
    }
}

Verwendungsbeispiel

print("lala".equalIgnoreCase("LALA"))
print("l4la".equalIgnoreCase("LALA"))
print("laLa".equalIgnoreCase("LALA"))
print("LALa".equalIgnoreCase("LALA"))
luhuiya
quelle
1
Dies funktioniert bei einigen Zeichenfolgen in einigen Sprachen nicht ... siehe die Kommentare unter der Frage und die vielen richtigen Antworten, von denen einige - einschließlich der akzeptierten - jahrelang Ihren vorausgingen.
Jim Balter
-2

Swift 3:

Sie können auch den lokalisierten Vergleich zwischen zwei Zeichenfolgen verwenden, bei dem die Groß- und Kleinschreibung nicht berücksichtigt wird und der zurückgegeben wird Bool

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

if a.localizedCaseInsensitiveContains(b) {
    print("Identical")           
} else {
    print("Non Identical")
}
Kegham K.
quelle
2
Ihre Lösung ist falsch. Betrachten Sie die Zeichenfolgen "casha" und "Cash"
clarkcox3