问题描述
我有一个 UISearchController,当用户输入文本时,它会搜索对象。但是用户只能搜索一个关键字,我希望他们搜索多个关键字。
型号:
struct DiagnosisDetails: Codable {
let diagnosisCodeId: Int
let diagnosisMappingId: Int
let diagnosisCode: String?
let bodyRegion: String?
let bodyPart: String?
let bodySite: String?
}
func filteredDiagnosis(for queryOrNil: String?) -> [DiagnosisDetails] {
guard let diagnosis = self.diagnosis,let query = queryOrNil,!query.isEmpty else { return [] }
let filteredDiagnosis: [DiagnosisDetails] = diagnosis.filter {
if let bodyPart = $0.bodyPart,let bodySite = $0.bodySite,let bodyRegion = $0.bodyRegion,let diagnosisCode = $0.diagnosisCode {
return (bodyPart.lowercased().contains(query.lowercased()) || bodySite.lowercased().contains(query.lowercased()) || bodyRegion.lowercased().contains(query.lowercased()) || diagnosisCode.lowercased().contains(query.lowercased()))
} else {
return false
}
}
return filteredDiagnosis
}
解决方法
您可以通过创建要查询的诊断字段的辅助字符串来简化搜索逻辑,然后查找与其匹配的任何子字符串。
首先,创建从诊断返回“主搜索字符串”的函数:
struct DiagnosisDetails: Codable,Hashable {
let diagnosisCodeId: Int
let diagnosisMappingId: Int
let diagnosisCode: String?
let bodyRegion: String?
let bodyPart: String?
let bodySite: String?
func getSearchString() -> String {
let bPart = bodyPart ?? ""
let bSite = bodySite ?? ""
let bRegion = bodyRegion ?? ""
let dCode = diagnosisCode ?? ""
return bPart + bSite + bRegion + dCode
}
}
然后简单的搜索函数如下:
func filteredDiagnosis(for queryOrNil: String?) -> [DiagnosisDetails] {
guard let diagnosis = self.diagnosis,let query = queryOrNil,!query.isEmpty else { return [] }
return diagnosis.filter({
return $0.getSearchString().range(of: query,options: .caseInsensitive) != nil
})
}
更新 多词搜索字符串过滤功能:思路很简单——将搜索查询拆分成词,过滤每个词匹配的诊断数组,并使用集合组合所有答案
func filteredDiagnosis(for queryOrNil: String?) -> [DiagnosisDetails] {
guard let diagnosis = self.diagnosis,!query.isEmpty else { return [] }
let searchWords = query.components(separatedBy: " ").filter({$0 != ""})
var filterResults = Set<DiagnosisDetails>()
for word in searchWords {
let wordResult = diagnosis.filter {$0.getSearchString().range(of: word,options: .caseInsensitive) != nil}
for res in wordResult { filterResults.insert(res) }
}
return Array(filterResults)
}