Swift 如何通过UISearchController实现多关键词数据过滤
多关键词搜索实现方案
核心实现思路
这套逻辑完全适配UISearchController的实时搜索回调,不需要额外增加触发逻辑,用户每输入一次文本,就会自动重新拆分关键词、刷新搜索结果,核心改动分为两步:
- 对用户输入的连续文本做预处理,拆分为独立的有效关键词,自动过滤首尾空格、连续空格产生的无效空字符串
- 调整原有过滤逻辑,从「整段输入匹配任意可搜索字段」,切换为匹配规则可自定义的多关键词判断,默认采用最符合用户搜索直觉的全关键词匹配(AND逻辑):即条目必须命中所有拆分出来的关键词,才算搜索结果
匹配规则可灵活调整:如果需要实现「命中任意一个关键词即返回结果(OR逻辑)」,只需要调整最后一步的判断方法即可。
修改后的完整代码
func filteredDiagnosis(for queryOrNil: String?) -> [DiagnosisDetails] { guard let diagnosis = self.diagnosis, let query = queryOrNil, !query.isEmpty else { return [] } // 1. 预处理输入,拆分有效关键词 let lowercasedQuery = query.lowercased() // 按空格拆分,过滤空字符串(处理多空格、首尾空格的异常输入场景) let keywords = lowercasedQuery .components(separatedBy: .whitespaces) .filter { !$0.isEmpty } // 拆分后没有有效关键词时直接返回空结果 guard !keywords.isEmpty else { return [] } let filteredDiagnosis = diagnosis.filter { item in // 提取条目所有可搜索的非nil文本字段,统一转小写做匹配 let searchableTexts = [ item.bodyPart?.lowercased(), item.bodySite?.lowercased(), item.bodyRegion?.lowercased(), item.diagnosisCode?.lowercased() ].compactMap { $0 } // 条目没有任何可搜索文本时直接排除 guard !searchableTexts.isEmpty else { return false } // AND逻辑:每个关键词都要至少在一个可搜索文本中命中 return keywords.allSatisfy { keyword in searchableTexts.contains { text in text.contains(keyword) } } // --- 如果要切换为OR逻辑(命中任意一个关键词就算匹配),替换上面的判断为下面这段即可 --- // return keywords.contains { keyword in // searchableTexts.contains { text in // text.contains(keyword) // } // } } return filteredDiagnosis }
相比原有逻辑的优化点
- 修复原代码的判断缺陷:原代码强制要求四个可搜索字段必须全部非nil才会参与匹配,只要有一个字段为nil就直接排除整个条目;新逻辑会自动跳过nil字段,只要剩余的非nil字段能命中关键词就正常返回结果,匹配覆盖率更高
- 自动兼容异常输入:用户连续输入多个空格、输入内容首尾带空格时,不会产生无效的空关键词导致匹配错误
- 搜索结果不受关键词输入顺序影响:拆分后独立判断每个关键词,不管用户按什么顺序输入关键词,只要所有关键词都能命中,就会返回对应的条目,符合日常搜索的使用习惯
内容的提问来源于stack exchange,提问作者isaacthedev
相关产品推荐
相关产品推荐

