64

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?

0

12 Answers 12

72

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
}
Sign up to request clarification or add additional context in comments.

Comments

33

you can use

word.lowercaseString 

to convert the string to all lowercase characters

Comments

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

4 Comments

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".
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 I would prefer containsCaseInsensitive or caseInsensitiveContains. Btw you can implement your own stackoverflow.com/a/41232801/2303865
@Leo Thank your suggestion. I use Swift now. I like its naming.
14

Swift 4

Just make everything (queries and results) case insensitive.

for item in listArray {
    if item.lowercased().contains(word.lowercased()) {
        searchResults.append(item)
    }
}

3 Comments

contains() should be equals(), here.
Just depends how you want the search to work. For search queries, I prefer contains.
this is inefficient - it will cause word to be lower-cased on every iteration.
13

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

1 Comment

Love this. Nice and clean :)
8

Try this:

let loword = word.lowercaseString
let found = contains(listArray) { $0.lowercaseString == loword }

Comments

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
}

Comments

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

Comments

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 :)

1 Comment

Note that it might occur more than once and this will give you only to the first index.
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
    }
}

Comments

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

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.