忽略 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
}