我有一个String类型的数组:
var Arr = ["apple", "banana", "orange", "grapes", "yellow banana", "urban"]
如何过滤具有my关键字前缀的数组中的每个单词? 现在我有了这个:
.filter { $0.contains(keyword) }
.sorted { ($0.hasPrefix(keyword) ? 0 : 1) < ($1.hasPrefix(keyword) ? 0 : 1) }
但如果我有关键字&#34; ban&#34;,它将返回&#34; banana&#34;,&#34; yellow banana&#34;和&#34; urban&#34;。 我只需要过滤数组元素中每个单词的前缀,以获得&#34; banana&#34;和&#34;黄香蕉&#34;。
答案 0 :(得分:2)
您需要先使用enumerateSubstrings方法将字符串拆分为单词,然后检查是否有任何单词包含关键字前缀:
extension String {
var words: [String] {
var words: [String] = []
enumerateSubstrings(in: startIndex..<endIndex, options: .byWords) { word,_,_,_ in
guard let word = word else { return }
words.append(word)
}
return words
}
}
let arr = ["apple", "banana", "orange", "grapes", "yellow banana", "urban"]
let keyword = "ban"
let filtered = arr.filter { $0.words.contains(where: {$0.hasPrefix(keyword)}) }
filtered // ["banana", "yellow banana"]
答案 1 :(得分:2)
您可以使用正则表达式检查关键字
发生在单词边界(\b
模式):
let array = ["apple", "banana", "orange", "grapes", "yellow banana", "urban"]
let keyword = "ban"
let pattern = "\\b" + NSRegularExpression.escapedPattern(for: keyword)
let filtered = array.filter {
$0.range(of: pattern, options: .regularExpression) != nil
}
print(filtered) // ["banana", "yellow banana"]
对于不区分大小写的搜索,请使用
options: [.regularExpression, .caseInsensitive]
代替。
答案 2 :(得分:1)
我只想引用由于过滤数组进行匹配而导致的时间复杂度。
例如:
private var words: [String]
func words(matching prefix: String) -> [String]
{
return words.filter { $0.hasPrefix(prefix) }
}
words(matching:)
将遍历字符串的集合并返回
匹配前缀的字符串。
如果单词数组中的元素数很少,则为 合理的策略。但是,如果您要处理的不止几个 一千个单词,经过单词数组所需的时间将 不可接受。 单词(匹配:)的时间复杂度为O(k * n), 其中k是集合中最长的字符串,n是 您需要检查的单词。
Trie 数据结构具有出色的性能特征 这种类型的问题。
参考:https://www.raywenderlich.com/892-swift-algorithm-club-swift-trie-data-structure
答案 3 :(得分:0)
或者在 Swift 3 + :
中let array = ["apple", "banana", "orange", "grapes", "yellow banana", "urban"]
let keyword = "ban"
let filtered = array.filter {
$0.components(separatedBy: " ").first { $0.hasPrefix(keyword) } != nil
}
print(filtered) // ["banana", "yellow banana"]
答案 4 :(得分:0)
您可以使用hasPrefix过滤数组,如下所示:
// I Use two arrays, actualArray with original data and filteredArray contains data after filtration. You can use whatever is best for your scenario
filteredArray = actaulArray.filter({ $0.hasPrefix(searchBar.text!) })