113

How can we compare two strings in swift ignoring case ? for eg :

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

Is there any method that will return true if we compare var a & var b

mfaani
  • 33,269
  • 19
  • 164
  • 293
ak_tyagi
  • 1,552
  • 2
  • 12
  • 20
  • 2
    You could convert both to lower case before doing comparison. – Dino Tw May 29 '15 at 14:59
  • 11
    Just to note that `lowercaseString` that is mentioned in some answers will fail in some languages (Straße != STRASSE for example) – Alladinian May 29 '15 at 15:02
  • @Alladinian how would you suggest doing it then. Most examples to solve this issue show converting to either all upper case or all lower case? – Steve May 29 '15 at 15:21
  • 5
    @Steve Apple suggests `caseInsensitiveCompare:` & `localizedCaseInsensitiveCompare:` instead – Alladinian May 29 '15 at 15:25
  • @Alladinian thank you, do those handle your example as well? – Steve May 29 '15 at 15:26
  • 3
    @Steve Sure! (you can try `"Straße".localizedCaseInsensitiveCompare("STRASSE")` - Remember to import `Foundation`) – Alladinian May 29 '15 at 15:30

17 Answers17

201

Try this :

For older swift:

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

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

Swift 3+

var a : String = "Cash"
var b : String = "cash"
    
if(a.caseInsensitiveCompare(b) == .orderedSame){
    print("Et voila")
}
iAnurag
  • 9,286
  • 3
  • 31
  • 48
  • 14
    In Swift 3 you need to use `a.caseInsensitiveCompare(b) == ComparisonResult.orderedSame` – azhidkov Sep 17 '16 at 08:07
  • 3
    Note: `caseInsensitiveCompare(_:)` is not included in the Swift Standard Library, rather it is part of the `Foundation` framework, thus, requiring `import Foundation`. – chrisamanse Nov 12 '16 at 00:51
  • Is there any reason why this is any better than `a.lowercased() == b.lowercased()` ? – jowie Sep 04 '20 at 12:41
  • 1
    @jowie as mentioned in the other comments, using lower/uppercased() may fail on certain languages. – cumanzor Oct 20 '20 at 21:41
  • 1
    `a.localizedStandardRange(of: b) == a.startIndex.. – Tomn Oct 07 '22 at 08:24
42

Use caseInsensitiveCompare method:

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

ComparisonResult tells you which word comes earlier than the other in lexicographic order (i.e. which one comes closer to the front of a dictionary). .orderedSame means the strings would end up in the same spot in the dictionary

mfaani
  • 33,269
  • 19
  • 164
  • 293
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • what does `.orderedSame` mean? The [docs](https://developer.apple.com/documentation/foundation/comparisonresult) just say _The two operands are equal_. But why is the word 'order' used here? Is there a sequence or something? And what does _The left operand is smaller than the right operand._ (`.orderedAscending`) mean for strings – mfaani Jun 29 '18 at 15:20
  • 1
    @Honey Comparison result tells you which word comes earlier than the other in lexicographic order (i.e. which one comes closer to the front of a dictionary). `.orderedSame` means the strings would end up in the same spot in the dictionary. – Sergey Kalinichenko Jun 29 '18 at 15:24
  • 1
    @Honey `.orderedSame` is short for `ComparisonResult.orderSame` ... you don't have to name the type since the compiler knows that `caseInsensitiveCompare` returns a `ComparisonResult`. "The two operands are equal" -- they are equal according to a specific ordering ... clearly, "Cash" and "cash" are not identical string values. "But why is the word 'order' used here?" -- because it's the result of an ordered comparison. The other values are `orderedAscending` and `orderedDescending` ... it's not just a question of same or different. As for "smaller": strings are like numbers in a large base. – Jim Balter Oct 10 '18 at 05:41
  • 2
    I feel like this is terrible API design. The signature is not easy to read...Making it `a.caseInsensitiveCompare(b, comparing: .orderedSame)` would have been more readable... – mfaani Oct 22 '18 at 03:15
26
if a.lowercaseString == b.lowercaseString {
    //Strings match
}
Steve
  • 1,371
  • 9
  • 13
  • 2
    Pure Swift is the way to go here. No need for foundation. – Alexander Jul 24 '16 at 15:39
  • 4
    Converting case and then comparing is wrong. See the comments under the question. – Jim Balter Feb 06 '17 at 03:30
  • 2
    @JimBalter I wouldn't say it's "wrong" since it answers the example given in the OP's question. For those of us who don't need to support localization this is much cleaner! – toddg Feb 07 '18 at 16:25
  • 9
    ^ No, it's wrong. That something happens to work for one example is irrelevant. This hack is not "cleaner" at all. The accepted answer gives the correct, clean solution. – Jim Balter Feb 07 '18 at 18:46
18

Try this:

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 is type of NSComparisonResult enum:

enum NSComparisonResult : Int {

    case OrderedAscending
    case OrderedSame
    case OrderedDescending
}

So you can use if statement:

if result == .OrderedSame {
    println("equal")
} else {
    println("not equal")
}
Greg
  • 25,317
  • 6
  • 53
  • 62
12

localizedCaseInsensitiveContains : Returns whether the receiver contains a given string by performing a case-insensitive, locale-aware search

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

Edited:

caseInsensitiveCompare : Returns the result of invoking compare(_:options:) with NSCaseInsensitiveSearch as the only option.

if a.caseInsensitiveCompare(b) == .orderedSame {
    //returns true if a equals b (case insensitive)
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
cgeek
  • 558
  • 5
  • 18
10

CORRECT WAY:

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

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

Please note: ComparisonResult.orderedSame can also be written as .orderedSame in shorthand.

OTHER WAYS:

a.

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

b.

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

c.

if a.capitalized() == b.capitalized() {
    //Strings match 
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
Saurabh Bhatia
  • 1,875
  • 1
  • 20
  • 29
6

Could just roll your own:

func equalIgnoringCase(a:String, b:String) -> Bool {
    return a.lowercaseString == b.lowercaseString
}
matt
  • 515,959
  • 87
  • 875
  • 1,141
2

Phone numbers comparison example; using 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")
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
ikbal
  • 1,110
  • 12
  • 21
1

You can just write your String Extension for comparison in just a few line of code

extension String {

    func compare(_ with : String)->Bool{
        return self.caseInsensitiveCompare(with) == .orderedSame
    } 
}
Mujahid Latif
  • 596
  • 7
  • 18
1

For Swift 5 Ignoring the case and compare two string

var a = "cash"
var b = "Cash"
if(a.caseInsensitiveCompare(b) == .orderedSame){
     print("Ok")
}
ikbal
  • 1,110
  • 12
  • 21
M Murteza
  • 1,629
  • 15
  • 10
0

Swift 4, I went the String extension route using caseInsensitiveCompare() as a template (but allowing the operand to be an optional). Here's the playground I used to put it together (new to Swift so feedback more than welcome).

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
  • 1,562
  • 2
  • 25
  • 33
0

Created an extension function for it. Pass caseSensitive as false if you want case insensitive compare.

extension String {
    
    func equals(to string: String, caseSensitive: Bool = true) -> Bool {
        if caseSensitive {
            return self.compare(string) == .orderedSame
        } else {
            return self.caseInsensitiveCompare(string) == .orderedSame
        }
    }
}

Example:

"cash".equals(to: "Cash", caseSensitive: false) //returns true
"cash".equals(to: "Cash") //returns false
Alif Hasnain
  • 1,176
  • 1
  • 11
  • 24
-1

Swift 3: You can define your own operator, e.g. ~=.

infix operator ~=

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

Which you then can try in a playground

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

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

test() // prints 'same'
Sajjon
  • 8,938
  • 5
  • 60
  • 94
  • 1
    I didn't downvote this, but note that this is generally a quite bad idea, since the custom pattern matching operator above will take precedence over the native pattern matching usually used when matching `String` instances to eachother (or to other `String` literals). Imagine `let str = "isCAMELcase"` being switched over, with a case as follows: `case "IsCamelCase": ... `. With the method above, this `case` would be entered successfully, which is not expected coming from the standard libs implementation of `String` pattern matching. An updated Swift 3 answer is still good though, but ... – dfrib Feb 19 '17 at 20:07
  • ... consider using a custom function (or `String` extension) as helper above rather than overriding the default `String` pattern matching. – dfrib Feb 19 '17 at 20:07
-2

You could also make all the letters uppercase (or lowercase) and see if they are the same.

var a = “Cash”
var b = “CASh”

if a.uppercaseString == b.uppercaseString{
  //DO SOMETHING
}

This will make both variables as ”CASH” and thus they are equal.

You could also make a String extension

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

if "Something ELSE".equalsIgnoreCase("something Else"){
  print("TRUE")
}
milo526
  • 5,012
  • 5
  • 41
  • 60
-2

Swift 3

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

}
DoubleK
  • 542
  • 3
  • 16
-3

Swift 3:

You can also use the localized case insensitive comparison between two strings function and it returns Bool

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

if a.localizedCaseInsensitiveContains(b) {
    print("Identical")           
} else {
    print("Non Identical")
}
Kegham K.
  • 1,589
  • 22
  • 40
-3
extension String
{
    func equalIgnoreCase(_ compare:String) -> Bool
    {
        return self.uppercased() == compare.uppercased()
    }
}

sample of use

print("lala".equalIgnoreCase("LALA"))
print("l4la".equalIgnoreCase("LALA"))
print("laLa".equalIgnoreCase("LALA"))
print("LALa".equalIgnoreCase("LALA"))
pkamb
  • 33,281
  • 23
  • 160
  • 191
luhuiya
  • 2,129
  • 21
  • 20
  • 3
    This doesn't work for some strings in some languages ... see the comments under the question, and the many correct answers, some of which -- including the accepted one -- preceded yours by years. – Jim Balter Oct 10 '18 at 05:48