过滤数组中的每个单词前缀

时间:2017-12-15 20:57:58

标签: arrays swift

我有一个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;。

5 个答案:

答案 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!)  })