在Swift中如何检查数组是否包含字符串的一部分?

27

我有一个包含多个字符串的数组。我已经使用了contains()(如下所示)来检查某个字符串是否存在于数组中,但我想检查字符串的一部分是否在数组中。

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

searchToSearch = "go"

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

上述代码仅仅检查数组中是否完全包含某个值,但我想要找到"Google, Google and Go"。
10个回答

31

试试这样做。

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将包含具有匹配子字符串的字符串列表。

在Swift中,Array结构提供了filter方法,该方法根据过滤文本条件对提供的数组进行过滤。


谢谢。如果我想明确检查数组是否因搜索而有任何内容,该怎么办? - Daniel Bramhall
如果我理解你的问题正确,你可以使用count来检查结果数组filteredStrings中是否有任何内容。使用这个 - filteredStrings.count - Amit89
2
在Swift 4.0中,rangeOfString被更改为range(of: "string"),而lowercaseString被更改为lowerCased()。 - Hammad Tariq
我使用这个解决方案过滤时间时遇到问题。我有一个由1000多个元素组成的 [Articles] 类型数组,我必须在每篇文章的描述中搜索,而每篇文章的描述都超过1500个单词。过滤需要太长时间了,大约2-3秒钟。 - Shahbaz Saleem

31

首先,您已经定义了一个只包含一个字符串的数组。

您可能想要的是

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

然后您可以使用contains(array, predicate)rangeOfString(),可选择与.CaseInsensitiveSearch配合使用, 逐个检查数组中的每个字符串是否包含搜索字符串:

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

println(itemExists) // true 

或者,如果您想要一个包含匹配项的数组而不是一个是/否结果:

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

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

更新 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)

为什么contains会有一个throw呢?难道它不是真或假吗? - mfaani
1
@Honey:你可以将一个 throwing closure 传递给 contains() 方法。如果该 closure 抛出错误,则由 contains() 方法重新抛出。- 参见 https://dev59.com/-lgQ5IYBdhLWcg3wGgH0。 - Martin R

15

试着这样做。

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)

输出

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

1
请不要多次发布相同的答案。如果问题已经在其他地方有了现有的答案,则应将问题标记为重复,而不是再次回答。谢谢。 - Eric Aya

10

在 Swift 5 中,具有更好的可读性:

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

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

这段代码实现了反向搜索 - 即在itemsArray中查找哪个项目是searchString的子字符串。语法使用得很好,但这并不能满足原始问题,因为searchString应该是items中某个项目的子字符串。 - mitrenegade

5

备注:- 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
}

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

0

最近我遇到了同样的问题,对大多数答案不是很满意,我是这样解决的:

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

这也将正确触发像“doc”这样的搜索,而许多上面的答案并不是最佳实践。 contains()比first() != nil更高效 来源:https://www.avanderlee.com/swift/performance-collections/


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

-1

Swift 5

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

1
请不要发布重复的答案。 - HangarRash

-1
如果您只是想检查特定数组中是否存在某个项,请尝试以下方法:
var a = [1,2,3,4,5]

if a.contains(4) {
    print("Yes, it does contain number 4")
}
else {
    print("No, it doesn't")
}

这不是被问到的内容,这只是匹配一个数组项,问题是匹配项的一部分。 - moonmonkey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接