问题
Is there a way to search through a UITableView and ignore certain characters like commas or dots?
I.e. I would like to search for "St George" but my data set contains "St. George" so the result is always zero.
EDITED Q:
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)"
}
回答1:
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:
edit/update Swift 5 or later
extension StringProtocol where Self: RangeReplaceableCollection {
func containsCaseInsensitive(_ string: String) -> Bool {
return range(of: string, options: .caseInsensitive) != nil
}
var letters: Self {
return filter{ $0.isLetter }
}
}
Testing:
let search = "st george"
let tableViewSource = ["Apple", "Orange", "Banana", "St. George"]
let filtered = tableViewSource.filter {
$0.letters.containsCaseInsensitive(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 { !$0.isPunctuation }
}
var removingPunctuation: Self {
return filter { !$0.isPunctuation }
}
}
Testing:
let filtered = tableViewSource.filter {
$0.removingPunctuation.caseInsensitiveContains(search.removingPunctuation)
}
print(filtered) // ["St. George"]
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 containsCaseInsensitiveCharactersInSequence(_ string: Self) -> Bool {
var found = 0
var start = startIndex
string.forEach {
while let range = self[start...].range(of: String($0), options: .caseInsensitive) {
found += 1
start = range.upperBound
break
}
}
return found == string.count
}
}
Playground Testing:
let search = "stgrge"
let tableViewSource = ["Apple", "Orange", "Banana", "St. George"]
let filtered = tableViewSource.filter {
$0.removingPunctuation.containsCaseInsensitiveCharactersInSequence(search.removingPunctuation)
}
print(filtered) // ["St. George"]
回答2:
I think you should simply implement a function that for any given string, will return te same string without any point, (or whatever you want to erase); such as :
func erase(characters: [String], fromText text: String) -> String {
var result = String()
for character in text.characters {
if !characters.contains(character) {
result += String(character)
}
}
return result
}
(I cant test it from where i am but you get the idea right ?)
Hope it helps
来源:https://stackoverflow.com/questions/41232236/searching-a-uitableview-and-ignoring-punctuation