搜索 UITableView 并忽略标点符号 [英] Searching a UITableView and ignoring punctuation
问题描述
有没有办法搜索 UITableView 并忽略某些字符(如逗号或点)?
Is there a way to search through a UITableView and ignore certain characters like commas or dots?
即我想搜索St George",但我的数据集包含St. George",因此结果始终为零.
I.e. I would like to search for "St George" but my data set contains "St. George" so the result is always zero.
已编辑的问题:
func filteredArray(searchText: NSString) {
if searchText == "" {
array_search = array_all
} else {
showTableViewResults()
array_search.removeAll()
for i in 0 ..< array_all.count {
let object:MyObject = array_all[i]
let languageSearchString = object.myObjectName
let searchStr:String = languageSearchString!
if searchStr.lowercased().contains(searchText.lowercased) {
array_search.append(object)
}
}
}
tableView.reloadData()
recordsFoundLabel.text = "records found: \(array_search.count)"
}
推荐答案
在执行搜索之前,您可以从字符串中过滤掉所有不是字母的字符.这同样适用于表视图数据源元素.同样如 rmaddy 所述,您应该实现不区分大小写的搜索:
You can filter all characters thats not a letter out of your String before performing your search. The same applies to the table view data source elements. Also as mentioned by rmaddy you should implement a case insensitive search:
编辑/更新 Swift 5.2 或更高版本
extension StringProtocol {
func caseInsensitiveContains<S: StringProtocol>(_ string: S) -> Bool { range(of: string, options: .caseInsensitive) != nil }
}
extension StringProtocol where Self: RangeReplaceableCollection {
var letters: Self { filter(\.isLetter) }
}
测试:
Testing:
let search = "st george"
let tableViewSource = ["Apple", "Orange", "Banana", "St. George"]
let filtered = tableViewSource.filter {
$0.letters.caseInsensitiveContains(search.letters)
}
print(filtered) // ["St. George"]
如果您只想从字面上删除字符串中的标点符号(请注意,这会保留字符串中的空格),您可以执行以下操作:
If you would like to literally just remove punctuation from your String (note that would keep the spaces in your String), you can do as follow:
extension StringProtocol where Self: RangeReplaceableCollection {
mutating func removePunctuation() { removeAll(where: \.isPunctuation) }
}
extension Bool {
var negated: Bool { !self }
}
extension StringProtocol where Self: RangeReplaceableCollection {
var removingPunctuation: Self { filter(\.isPunctuation.negated) }
}
测试:
Testing:
let filtered = tableViewSource.filter {
$0.removingPunctuation.caseInsensitiveContains(search.removingPunctuation)
}
print(filtered) // ["St. George"]
如果您想实现与 Xcode 自动完成相同的逻辑,您需要搜索每个字符并更改搜索字符串的 startIndex:
If you would like to implement the same logic as Xcode autocomplete you would need to do a search for each character and change the startIndex of the string searched:
extension StringProtocol where Self: RangeReplaceableCollection {
func containsCharactersInSequence<S: StringProtocol>(_ string: S, options: String.CompareOptions = []) -> (result: Bool, ranges: [Range<Index>]) {
var found = 0
var startIndex = self.startIndex
var index = string.startIndex
var ranges: [Range<Index>] = []
while index < string.endIndex,
let range = self[startIndex...].range(of: string[index...index], options: options) {
ranges.append(range)
startIndex = range.upperBound
string.formIndex(after: &index)
found += 1
}
return (found == string.count, ranges)
}
}
游乐场测试:
Playground Testing:
let search = "stgre"
let tableViewSource = ["Apple", "Orange", "Banana", "St. George"]
let filtered = tableViewSource.filter {
$0.containsCharactersInSequence(search, options: .caseInsensitive).result
}
print(filtered) // ["St. George"]
这篇关于搜索 UITableView 并忽略标点符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!