Check if a string exists in an array case insensitively
Asked Answered
D

12

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?

Dovap answered 9/7, 2015 at 22:45 Comment(0)
S
31

you can use

word.lowercaseString 

to convert the string to all lowercase characters

Stench answered 9/7, 2015 at 22:57 Comment(0)
K
71

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
}
Kiesha answered 10/7, 2015 at 0:16 Comment(0)
S
31

you can use

word.lowercaseString 

to convert the string to all lowercase characters

Stench answered 9/7, 2015 at 22:57 Comment(0)
T
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

Typewriting answered 12/9, 2016 at 7:49 Comment(4)
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".Heliotropin
https://mcmap.net/q/302878/-localizedcaseinsensitivecontainsstring-not-available-in-swift localizedCaseInsensitiveContainsString seems a method in NSString. But I don't like it's method signature. Maybe containsIgnoringCase is better naming.Sclerenchyma
@Sclerenchyma I would prefer containsCaseInsensitive or caseInsensitiveContains. Btw you can implement your own https://mcmap.net/q/302879/-searching-a-uitableview-and-ignoring-punctuationKiesha
@Leo Thank your suggestion. I use Swift now. I like its naming.Sclerenchyma
A
14

Swift 4

Just make everything (queries and results) case insensitive.

for item in listArray {
    if item.lowercased().contains(word.lowercased()) {
        searchResults.append(item)
    }
}
Australoid answered 25/11, 2017 at 20:15 Comment(3)
contains() should be equals(), here.Paramagnetic
Just depends how you want the search to work. For search queries, I prefer contains.Australoid
this is inefficient - it will cause word to be lower-cased on every iteration.Arella
H
12

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
Herbherbaceous answered 7/5, 2020 at 23:7 Comment(1)
Love this. Nice and clean :)Turd
S
8

Try this:

let loword = word.lowercaseString
let found = contains(listArray) { $0.lowercaseString == loword }
Scalable answered 9/7, 2015 at 23:0 Comment(0)
L
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
}
Lucullus answered 13/12, 2018 at 11:37 Comment(0)
S
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")
}
Succor answered 8/1, 2020 at 10:49 Comment(0)
L
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 :)

Lafayette answered 5/9, 2017 at 17:49 Comment(1)
Note that it might occur more than once and this will give you only to the first index.Kiesha
C
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
    }
}
Crescendo answered 1/1, 2020 at 15:43 Comment(0)
R
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()
}
Reremouse answered 13/4, 2016 at 7:46 Comment(0)
S
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 })
Spermiogenesis answered 2/1, 2022 at 16:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.