27

I have an array containing a number of strings. I have used contains() (see below) to check if a certain string exists in the array however I would like to check if part of a string is in the array?

itemsArray = ["Google, Goodbye, Go, Hello"]

searchToSearch = "go"

if contains(itemsArray, stringToSearch) {
    NSLog("Term Exists")
}
else {
    NSLog("Can't find term")
}

The above code simply checks if a value is present within the array in its entirety however I would like to find "Google, Google and Go"

9 Answers 9

32

First of all, you have defined an array with a single string. What you probably want is

let itemsArray = ["Google", "Goodbye", "Go", "Hello"]

Then you can use contains(array, predicate) and rangeOfString() – optionally with .CaseInsensitiveSearch – to check each string in the array if it contains the search string:

let itemExists = contains(itemsArray) {
    $0.rangeOfString(searchToSearch, options: .CaseInsensitiveSearch) !=  nil
}

println(itemExists) // true 

Or, if you want an array with the matching items instead of a yes/no result:

let matchingTerms = filter(itemsArray) {
    $0.rangeOfString(searchToSearch, options: .CaseInsensitiveSearch) !=  nil
}

println(matchingTerms) // [Google, Goodbye, Go]

Update for Swift 3:

let itemExists = itemsArray.contains(where: {
    $0.range(of: searchToSearch, options: .caseInsensitive) != nil
})
print(itemExists)

let matchingTerms = itemsArray.filter({
    $0.range(of: searchToSearch, options: .caseInsensitive) != nil
})
print(matchingTerms)
Sign up to request clarification or add additional context in comments.

2 Comments

why does the contains have a throw? Isn't it either true or false?
@Honey: You can pass a throwing closure to the contains() method. If the closure throws an error then it is rethrown by contains(). – Compare stackoverflow.com/questions/43305051/….
31

Try like this.

let itemsArray = ["Google", "Goodbye", "Go", "Hello"]
let searchToSearch = "go"

let filteredStrings = itemsArray.filter({(item: String) -> Bool in

     var stringMatch = item.lowercaseString.rangeOfString(searchToSearch.lowercaseString)
     return stringMatch != nil ? true : false
})

filteredStrings will contain the list of strings having matched sub strings.

In Swift Array struct provides filter method, which will filter a provided array based on filtering text criteria.

4 Comments

Thanks for that. How would I explicitly check if the array had anything in it as a result of the search?
If i understand your question correctly, you can use count to check wether anything there in the result array filteredStrings. Use this - filteredStrings.count
In Swift 4.0 rangeOfString is changed to range(of: "string") and lowercaseString is changed to lowerCased()
I have problem with filter time using this solution. I have an array of Type [Articles] with 1000+ elements and I have to search in description of that article and the description of each article is 1500+ words. filtering is taking too much time. Around 2-3 seconds.
15

Try like this.

Swift 3.0

import UIKit

let itemsArray = ["Google", "Goodbye", "Go", "Hello"]

var filterdItemsArray = [String]()


func filterContentForSearchText(searchText: String) {
    filterdItemsArray = itemsArray.filter { item in
        return item.lowercased().contains(searchText.lowercased())
    }
}

filterContentForSearchText(searchText: "Go")
print(filterdItemsArray)

Output

["Google", "Goodbye", "Go"]

1 Comment

Please do not post the same answer multiple times. If a question already has an existing answer elsewhere, then flag the question as duplicate instead of answering again. Thanks.
10

In Swift 5 with better readability :

let itemsArray = ["Google", "Goodbye", "Go", "Hello"]
let searchString = "Googled"

let result = itemsArray.contains(where: searchString.contains)
print(result) //prints true in the above case.

1 Comment

this does the reverse search - which item in the itemsArray is a substring of the searchString. Nice use of syntax but this will not satisfy the original question, where the searchString should be a substring of one of the items.
5

MARK:- Swift 5, Swift 4

//MARK:- You will find the array when its filter in "filteredStrings" variable you can check it by count if count > 0 its means you have find the results

let itemsArray = ["Google", "Goodbye", "Go", "Hello"]
let searchToSearch = "go"

let filteredStrings = itemsArray.filter({(item: String) -> Bool in

    let stringMatch = item.lowercased().range(of: searchToSearch.lowercased())
    return stringMatch != nil ? true : false
})
print(filteredStrings)


if (filteredStrings as NSArray).count > 0
{
    //Record found
    //MARK:- You can also print the result and can do any kind of work with them
}
else
{
    //Record Not found
}

Comments

1
func filterContentForSearchText(_ searchText: String) {
   filteredString = itemsArray.filter({( item : String) -> Bool in
            return  item.lowercased().contains(searchText.lowercased())
    })
}

Comments

0

In Swift 4:

    let itemsArray = ["Google", "Goodbye", "Go", "Hello"]
    let searchString = "Go"
    let filterArray = itemsArray.filter({ { $0.range(of: searchString, options: .caseInsensitive) != nil}
    })
    print(filterArray)

Comments

0

I had the same problem recently, didn't like most of these answers, solved it like this:

let keywords = ["doctor", "hospital"] //your array

func keywordsContain(text: String) -> Bool { // text: your search text
    return keywords.contains { (key) -> Bool in
        key.lowercased().contains(text.lowercased())
    }
}

This will also correctly trigger searches like "doc", which many of the above answers do not and is best practice. contains() is more performant than first() != nil source: https://www.avanderlee.com/swift/performance-collections/

Comments

-1

Swift 5

let itemExist = itemsArray.contains {
    $0.range(of: stringToSearch) != nil
}

1 Comment

Please don't post duplicate answers.

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.