Comment comparer deux chaînes en ignorant la casse en langage Swift?

95

Comment pouvons-nous comparer deux chaînes en cas d'ignorance rapide? par exemple:

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

Y a-t-il une méthode qui retournera true si nous comparons var a et var b

ak_tyagi
la source
1
Vous pouvez convertir les deux en minuscules avant de faire la comparaison.
Dino Tw
8
Juste pour noter que lowercaseStringcela est mentionné dans certaines réponses échouera dans certaines langues (Straße! = STRASSE par exemple)
Alladinian
@Alladinian comment suggéreriez-vous de le faire alors. La plupart des exemples pour résoudre ce problème montrent la conversion en majuscules ou en minuscules?
Steve
5
@Steve Apple suggère caseInsensitiveCompare:et à la localizedCaseInsensitiveCompare:place
Alladinian
3
@Steve bien sûr! (vous pouvez essayer "Straße".localizedCaseInsensitiveCompare("STRASSE")- N'oubliez pas d'importer Foundation)
Alladinian

Réponses:

13

Essaye ça:

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)

result est le type de NSComparisonResult enum:

enum NSComparisonResult : Int {

    case OrderedAscending
    case OrderedSame
    case OrderedDescending
}

Vous pouvez donc utiliser l'instruction if:

if result == .OrderedSame {
    println("equal")
} else {
    println("not equal")
}
Greg
la source
Si je me souviens bien, les paramètres de plage et de paramètres régionaux sont facultatifs et peuvent être entièrement omis.
Mick MacCallum
3
Oui en effet, je voulais montrer toute la méthode avec tous les paramètres.
Greg
Vous devriez avoir la bonne réponse ici. Comparer des chaînes ne consiste pas seulement à savoir si elles sont égales ou non
Mikael
181

Essaye ça :

Pour les swift plus âgés:

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
la source
13
Dans Swift 3, vous devez utilisera.caseInsensitiveCompare(b) == ComparisonResult.orderedSame
azhidkov
2
Remarque: caseInsensitiveCompare(_:)n'est pas inclus dans la bibliothèque standard Swift, mais fait plutôt partie du Foundationframework, donc, nécessitant import Foundation.
chrisamanse
Y a-t-il une raison pour laquelle c'est mieux que a.lowercased() == b.lowercased()?
jowie le
36

Utilisez la caseInsensitiveCompareméthode:

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

ComparisonResult vous indique quel mot vient plus tôt que l'autre dans l'ordre lexicographique (c'est-à-dire lequel se rapproche le plus du début d'un dictionnaire). .orderedSamesignifie que les chaînes finiraient au même endroit dans le dictionnaire

dasblinkenlight
la source
que veut .orderedSamedire? La documentation dit simplement que les deux opérandes sont égaux . Mais pourquoi le mot «ordre» est-il utilisé ici? Y a-t-il une séquence ou quelque chose? Et que fait L'opérande gauche est plus petit que l'opérande droit. ( .orderedAscending) signifie pour les chaînes
Honey
1
Le résultat @Honey Comparison vous indique quel mot vient plus tôt que l'autre dans l'ordre lexicographique (c.-à-d. Lequel se rapproche le plus du début d'un dictionnaire). .orderedSamesignifie que les chaînes se retrouveraient au même endroit dans le dictionnaire.
dasblinkenlight
1
@Honey .orderedSameest l'abréviation de ComparisonResult.orderSame... vous n'avez pas besoin de nommer le type puisque le compilateur sait que caseInsensitiveComparerenvoie un ComparisonResult. "Les deux opérandes sont égaux" - ils sont égaux selon un ordre spécifique ... clairement, "Cash" et "Cash" ne sont pas des valeurs de chaîne identiques. "Mais pourquoi le mot" ordre "est-il utilisé ici?" - parce que c'est le résultat d'une comparaison ordonnée. Les autres valeurs sont orderedAscendinget orderedDescending... ce n'est pas seulement une question de même ou de différent. Quant à "plus petit": les chaînes sont comme des nombres dans une grande base.
Jim Balter
1
J'ai l'impression que c'est une conception d'API terrible. La signature n'est pas facile à lire ... La rendre a.caseInsensitiveCompare(b, comparing: .orderedSame)aurait été plus lisible ...
Chérie
25
if a.lowercaseString == b.lowercaseString {
    //Strings match
}
Steve
la source
2
Pure Swift est la voie à suivre ici. Pas besoin de fondations.
Alexander - Réintégrer Monica le
2
Convertir le cas puis comparer est faux. Voir les commentaires sous la question.
Jim Balter le
1
@JimBalter Je ne dirais pas que c'est "faux" car il répond à l'exemple donné dans la question du PO. Pour ceux d'entre nous qui n'ont pas besoin de prendre en charge la localisation, c'est beaucoup plus propre!
toddg
4
^ Non, c'est faux. Que quelque chose arrive à fonctionner pour un exemple n'est pas pertinent. Ce hack n'est pas du tout "plus propre". La réponse acceptée donne la solution correcte et propre.
Jim Balter
8

BONNE MANIÈRE:

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

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

Notez s'il vous plaît: ComparisonResult.orderedSame peut également être écrit sous la forme .orderedSame en raccourci.

D'AUTRES MOYENS:

une.

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
la source
7

Pourrait juste rouler le vôtre:

func equalIgnoringCase(a:String, b:String) -> Bool {
    return a.lowercaseString == b.lowercaseString
}
mat
la source
3
Convertir le cas puis comparer est faux. Voir les commentaires sous la question.
Jim Balter
6

localizedCaseInsensitiveContains : renvoie si le récepteur contient une chaîne donnée en effectuant une recherche insensible à la casse et tenant compte des paramètres régionaux

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

Modifié :

caseInsensitiveCompare : renvoie le résultat de l'appel de compare (_: options :) avec NSCaseInsensitiveSearch comme seule option.

if a.caseInsensitiveCompare(b) == .orderedSame {
    //returns true if a equals b (case insensitive)
}
cgeek
la source
1
La question porte sur la comparaison, pas sur le confinement.
Jim Balter
Si "a contient b" et "b contient a" , ils sont égaux. C'est donc sûrement une solution possible, même si ce n'est peut-être pas la plus efficace.
Philipp Maurer
1

Vous pouvez également mettre toutes les lettres en majuscules (ou en minuscules) et voir si elles sont identiques.

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

Cela rendra les deux variables comme ”CASH”et donc elles sont égales.

Vous pouvez également créer une Stringextension

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

if "Something ELSE".equalsIgnoreCase("something Else"){
  print("TRUE")
}
milo526
la source
3
Convertir le cas puis comparer est faux. Voir les commentaires sous la question.
Jim Balter le
1

Exemple de comparaison de numéros de téléphone; en utilisant 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
la source
0

Swift 4, j'ai choisi la route d'extension String en utilisant caseInsensitiveCompare () comme modèle (mais en permettant à l'opérande d'être facultatif). Voici le terrain de jeu que j'ai utilisé pour le mettre en place (nouveau sur Swift, donc les commentaires sont les bienvenus).

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
la source
2
Vous pouvez simplement utiliser .orderedSameplutôt que ComparisonResult.orderedSame.
Jim Balter
0

Vous pouvez simplement écrire votre extension de chaîne à des fins de comparaison en quelques lignes de code

extension String {

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

Pour Swift 5 Ignorer le cas et comparer deux cordes

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

Swift 3

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

}
DoubleK
la source
2
C'est faux. Voir les commentaires sous la question.
Jim Balter
-1

Swift 3 : Vous pouvez définir votre propre opérateur, par exemple ~=.

infix operator ~=

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

Que vous pouvez ensuite essayer dans une aire de jeux

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

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

test() // prints 'same'
Sajjon
la source
Je n'ai pas voté contre cela, mais notez que c'est généralement une très mauvaise idée, car l'opérateur de correspondance de modèle personnalisé ci-dessus aura la priorité sur la correspondance de modèle native généralement utilisée lors de la correspondance des Stringinstances entre elles (ou avec d'autres Stringlittéraux). Imaginez let str = "isCAMELcase"être basculé, avec un cas comme suit: case "IsCamelCase": ... . Avec la méthode ci-dessus, cela caseserait entré avec succès, ce qui ne devrait pas provenir de l'implémentation standard des bibliothèques de Stringcorrespondance de modèles. Une réponse Swift 3 mise à jour est toujours bonne, mais ...
dfri
... envisagez d'utiliser une fonction personnalisée (ou une Stringextension) comme aide ci-dessus plutôt que de remplacer la Stringcorrespondance de modèle par défaut .
dfri
-1
extension String
{
    func equalIgnoreCase(_ compare:String) -> Bool
    {
        return self.uppercased() == compare.uppercased()
    }
}

échantillon d'utilisation

print("lala".equalIgnoreCase("LALA"))
print("l4la".equalIgnoreCase("LALA"))
print("laLa".equalIgnoreCase("LALA"))
print("LALa".equalIgnoreCase("LALA"))
luhuiya
la source
1
Cela ne fonctionne pas pour certaines chaînes dans certaines langues ... voir les commentaires sous la question, et les nombreuses réponses correctes, dont certaines - y compris celle acceptée - ont précédé les vôtres d'années.
Jim Balter
-2

Swift 3:

Vous pouvez également utiliser la fonction de comparaison localisée insensible à la casse entre deux chaînes et elle renvoie Bool

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

if a.localizedCaseInsensitiveContains(b) {
    print("Identical")           
} else {
    print("Non Identical")
}
Kegham K.
la source
2
Votre solution est incorrecte. Considérez les chaînes "casha" et "Cash"
clarkcox3