忽略 Swift 中的顺序搜索多个单词 5
Search for multiple words ignoring the order in Swift 5
在我的应用程序中,我构建了一个 SearchBar,对于单个单词,它工作得非常好。
导入基金会
class Clinic {
var id = ""
var name = ""
var address = ""
var specialty1 = ""
var specialty2 = ""
}
在我的 textDidChange 中有
var clinics: [Clinic] = [] // Clinics Data Structure
var clinicsSearch: [Clinic] = [] // Filtered Clinics
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
// works for one word (either in name or specialty1 or specialty2)
clinicsSearch = clinics.filter { [=12=].name.lowercased().contains(searchText.lowercased()) ||
[=12=].specialty1.lowercased().contains(searchText.lowercased()) ||
[=12=].specialty2.lowercased().contains(searchText.lowercased())
}
searching = true
tableView.reloadData()
}
使用上面的函数,如果我开始输入一些东西,它会带来所有符合条件的结果(如果输入的单词在 Name OR Specialty1 OR Specialty2 中找到)。
我现在开始寻求改进我的代码并希望实现一个选项,用户可以在其中以不同的顺序键入单词,例如:名称 SPACE specialty(1or2), specialty(1or2) ) SPACE 姓名等,应用程序将在所有 3 个字段中搜索所有键入的单词。顺序无关。
我在这里找到了与我正在寻找的非常相似的东西,但我无法在那里询问,因为我的声誉低于 50
与此处提供的解决方案的主要区别在于它们在示例中使用基本数组
let filterArray = ["Big green bubble", "Red bubble", "A bubble in green", "Small green bubble", "This bubble is green"]
这与我的不同,那是基于上面的 Class 诊所。我尝试根据我的情况调整他们的代码,如下所示
let textString = searchText.lowercased()
let words = textString.components(separatedBy: " ")
clinicsSearch = clinics.map { [=14=].name.lowercased() }.filter { string in words.allSatisfy { string.components(separatedBy: " ").contains([=14=]) } }
但是我得到了几个错误,比如'Clinic'类型的值没有成员'lowercased'或者'Clinic'类型的值没有成员'components'(还有其他的),我不知道如何修复。
非常感谢任何帮助。
谢谢
你可以试试
let searArr = searchText.lowercased().components(separatedBy: " ")
clinicsSearch = clinics.filter { item in
let res = searArr.filter { item.name.lowercased().contains([=10=]) ||
item.specialty1.lowercased().contains([=10=]) ||
item.specialty2.lowercased().contains([=10=])
}
return !res.isEmpty
}
这样做会更好
let searArr = searchText.lowercased().components(separatedBy: " ")
clinicsSearch = clinics.filter { item in
let lowName = item.name.lowercased()
let lowSp1 = item.specialty1.lowercased()
let lowSp2 = item.specialty2.lowercased()
let res = searArr.filter {
lowName.contains([=11=]) ||
lowSp1.contains([=11=]) ||
lowSp2.contains([=11=])
}
return !res.isEmpty
}
在我的应用程序中,我构建了一个 SearchBar,对于单个单词,它工作得非常好。
导入基金会
class Clinic {
var id = ""
var name = ""
var address = ""
var specialty1 = ""
var specialty2 = ""
}
在我的 textDidChange 中有
var clinics: [Clinic] = [] // Clinics Data Structure
var clinicsSearch: [Clinic] = [] // Filtered Clinics
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
// works for one word (either in name or specialty1 or specialty2)
clinicsSearch = clinics.filter { [=12=].name.lowercased().contains(searchText.lowercased()) ||
[=12=].specialty1.lowercased().contains(searchText.lowercased()) ||
[=12=].specialty2.lowercased().contains(searchText.lowercased())
}
searching = true
tableView.reloadData()
}
使用上面的函数,如果我开始输入一些东西,它会带来所有符合条件的结果(如果输入的单词在 Name OR Specialty1 OR Specialty2 中找到)。
我现在开始寻求改进我的代码并希望实现一个选项,用户可以在其中以不同的顺序键入单词,例如:名称 SPACE specialty(1or2), specialty(1or2) ) SPACE 姓名等,应用程序将在所有 3 个字段中搜索所有键入的单词。顺序无关。
我在这里找到了与我正在寻找的非常相似的东西,但我无法在那里询问,因为我的声誉低于 50
与此处提供的解决方案的主要区别在于它们在示例中使用基本数组
let filterArray = ["Big green bubble", "Red bubble", "A bubble in green", "Small green bubble", "This bubble is green"]
这与我的不同,那是基于上面的 Class 诊所。我尝试根据我的情况调整他们的代码,如下所示
let textString = searchText.lowercased()
let words = textString.components(separatedBy: " ")
clinicsSearch = clinics.map { [=14=].name.lowercased() }.filter { string in words.allSatisfy { string.components(separatedBy: " ").contains([=14=]) } }
但是我得到了几个错误,比如'Clinic'类型的值没有成员'lowercased'或者'Clinic'类型的值没有成员'components'(还有其他的),我不知道如何修复。
非常感谢任何帮助。
谢谢
你可以试试
let searArr = searchText.lowercased().components(separatedBy: " ")
clinicsSearch = clinics.filter { item in
let res = searArr.filter { item.name.lowercased().contains([=10=]) ||
item.specialty1.lowercased().contains([=10=]) ||
item.specialty2.lowercased().contains([=10=])
}
return !res.isEmpty
}
这样做会更好
let searArr = searchText.lowercased().components(separatedBy: " ")
clinicsSearch = clinics.filter { item in
let lowName = item.name.lowercased()
let lowSp1 = item.specialty1.lowercased()
let lowSp2 = item.specialty2.lowercased()
let res = searArr.filter {
lowName.contains([=11=]) ||
lowSp1.contains([=11=]) ||
lowSp2.contains([=11=])
}
return !res.isEmpty
}