61

Declaration:

let listArray = ["kashif"]
let word = "kashif"

then this

contains(listArray, word) 

Returns true but if declaration is:

let word = "Kashif"

then it returns false because comparison is case sensitive.

How to make this comparison case insensitive?

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Kashif
  • 4,642
  • 7
  • 44
  • 97

12 Answers12

66

Xcode 8 • Swift 3 or later

let list = ["kashif"]
let word = "Kashif"

if list.contains(where: {$0.caseInsensitiveCompare(word) == .orderedSame}) {
    print(true)  // true
}

alternatively:

if list.contains(where: {$0.compare(word, options: .caseInsensitive) == .orderedSame}) {
    print(true)  // true
}

if you would like to know the position(s) of the element in the array (it might find more than one element that matches the predicate):

let indices = list.indices.filter { list[$0].caseInsensitiveCompare(word) == .orderedSame }
print(indices)  // [0]

You can also use localizedStandardContains method which is case and diacritic insensitive and would match a substring as well:

func localizedStandardContains<T>(_ string: T) -> Bool where T : StringProtocol

Discussion This is the most appropriate method for doing user-level string searches, similar to how searches are done generally in the system. The search is locale-aware, case and diacritic insensitive. The exact list of search options applied may change over time.

let list = ["kashif"]
let word = "Káshif"

if list.contains(where: {$0.localizedStandardContains(word) }) {
    print(true)  // true
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
30

you can use

word.lowercaseString 

to convert the string to all lowercase characters

Charlie Hall
  • 547
  • 4
  • 7
19

For checking if a string exists in a array (case insensitively), please use

listArray.localizedCaseInsensitiveContainsString(word) 

where listArray is the name of array and word is your searched text

This code works in Swift 2.2

ios
  • 955
  • 1
  • 12
  • 35
  • 1
    Please edit with more information. Code-only and "try this" answers are discouraged, because they contain no searchable content, and don't explain why someone should "try this". – abarisone Sep 12 '16 at 08:35
  • http://stackoverflow.com/a/26175437/419348 `localizedCaseInsensitiveContainsString` seems a method in `NSString`. But I don't like it's method signature. Maybe `containsIgnoringCase ` is better naming. – AechoLiu Feb 10 '17 at 08:43
  • 1
    @AechoLiu I would prefer containsCaseInsensitive or caseInsensitiveContains. Btw you can implement your own https://stackoverflow.com/a/41232801/2303865 – Leo Dabus Sep 21 '18 at 16:05
  • 1
    @Leo Thank your suggestion. I use Swift now. I like [its naming](https://stackoverflow.com/a/30533007/419348). – AechoLiu Sep 25 '18 at 03:27
14

Swift 4

Just make everything (queries and results) case insensitive.

for item in listArray {
    if item.lowercased().contains(word.lowercased()) {
        searchResults.append(item)
    }
}
lurning too koad
  • 2,698
  • 1
  • 17
  • 47
10

You can add an extension:

Swift 5

extension Array where Element == String {
    func containsIgnoringCase(_ element: Element) -> Bool {
        contains { $0.caseInsensitiveCompare(element) == .orderedSame }
    }
}

and use it like this:

["tEst"].containsIgnoringCase("TeSt") // true
Alaeddine
  • 6,104
  • 3
  • 28
  • 45
8

Try this:

let loword = word.lowercaseString
let found = contains(listArray) { $0.lowercaseString == loword }
Mario Zannone
  • 2,843
  • 12
  • 18
5

For checking if a string exists in a array with more Options(caseInsensitive, anchored/search is limited to start)

using Foundation range(of:options:)

let list = ["kashif"]
let word = "Kashif"


if list.contains(where: {$0.range(of: word, options: [.caseInsensitive, .anchored]) != nil}) {
    print(true)  // true
}

if let index = list.index(where: {$0.range(of: word, options: [.caseInsensitive, .anchored]) != nil}) {
    print("Found at index \(index)")  // true
}
Govind Kumawat
  • 1,562
  • 1
  • 10
  • 17
3

swift 5, swift 4.2 , use the code in the below.

let list = ["kAshif"]
let word = "Kashif"

if list.contains(where: { $0.caseInsensitiveCompare(word) == .orderedSame }) {
    print("contains is true")
}
Zgpeace
  • 3,927
  • 33
  • 31
2

SWIFT 3.0:

Finding a case insensitive string in a string array is cool and all, but if you don't have an index it can not be cool for certain situations.

Here is my solution:

let stringArray = ["FOO", "bar"]()
if let index = stringArray.index(where: {$0.caseInsensitiveCompare("foo") == .orderedSame}) {
   print("STRING \(stringArray[index]) FOUND AT INDEX \(index)")
   //prints "STRING FOO FOUND AT INDEX 0"                                             
}

This is better than the other answers b/c you have index of the object in the array, so you can grab the object and do whatever you please :)

Josh O'Connor
  • 4,694
  • 7
  • 54
  • 98
1

Expanding on @Govind Kumawat's answer

The simple comparison for a searchString in a word is:

word.range(of: searchString, options: .caseInsensitive) != nil

As functions:

func containsCaseInsensitive(searchString: String, in string: String) -> Bool {
    return string.range(of: searchString, options: .caseInsensitive) != nil
}

func containsCaseInsensitive(searchString: String, in array: [String]) -> Bool {
    return array.contains {$0.range(of: searchString, options: .caseInsensitive) != nil}
}

func caseInsensitiveMatches(searchString: String, in array: [String]) -> [String] {
    return array.compactMap { string in
        return string.range(of: searchString, options: .caseInsensitive) != nil
            ? string
            : nil
    }
}
Ryan H
  • 1,656
  • 14
  • 15
0

My example

func updateSearchResultsForSearchController(searchController: UISearchController) {
    guard let searchText = searchController.searchBar.text else { return }
    let countries = Countries.getAllCountries()
    filteredCountries = countries.filter() {
        return $0.name.containsString(searchText) || $0.name.lowercaseString.containsString(searchText)
    }
    self.tableView.reloadData()
}
Alexander Khitev
  • 6,417
  • 13
  • 59
  • 115
0

If anyone is looking to search values from within model class, say

struct Country {
   var name: String
}

One case do case insensitive checks like below -

let filteredList = countries.filter({ $0.name.range(of: "searchText", options: .caseInsensitive) != nil })
Pankaj Gaikar
  • 2,357
  • 1
  • 23
  • 29