【问题标题】:Search for multiple words ignoring the order in Swift 5在 Swift 5 中搜索多个单词忽略顺序
【发布时间】:2019-11-12 00:08:12
【问题描述】:

在我的应用程序中,我构建了一个 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 { $0.name.lowercased().contains(searchText.lowercased()) ||
        $0.specialty1.lowercased().contains(searchText.lowercased()) ||
        $0.specialty2.lowercased().contains(searchText.lowercased())
    }
    searching = true
    tableView.reloadData()
}

使用上面的func,如果我开始输入一些东西,它会带来所有符合条件的结果(如果输入的单词在Name OR Specialty1 OR Specialty2中找到)。

我现在开始寻求改进我的代码并希望实现一个选项,用户可以按不同的顺序键入单词,例如:名称空间专业(1or2),专业(1or2)空间名称等,应用程序将在所有 3 个字段中搜索所有键入的单词。订单无关。

我在这里找到了与我正在寻找的非常相似的东西,但我无法在那里询问,因为我的声望低于 50 Search for multiple words ignoring the order in Swift

与那里提出的解决方案的主要区别在于它们在示例中使用基本的数组

let filterArray = ["Big green bubble", "Red bubble", "A bubble in green", "Small green bubble", "This bubble is green"]

这与我的不同,基于上面的班级诊所。我试图让他们的代码适应我的情况,如下所示

let textString = searchText.lowercased()
let words = textString.components(separatedBy: " ")
clinicsSearch = clinics.map { $0.name.lowercased() }.filter { string in words.allSatisfy { string.components(separatedBy: " ").contains($0) } }

但我遇到了几个错误,例如“诊所”类型的值没有“小写”成员或“诊所”类型的值没有成员“组件”(还有其他成员),我不知道如何解决.

非常感谢任何帮助。

谢谢

【问题讨论】:

  • 把最后一行改成clinicasSearch = clinicas.map { $0.name.lowercased() }.filter { string in words.allSatisfy { string.components(separatedBy: " ").contains($0) } }
  • 嗨@Koen,我也尝试过仍然得到相同的错误(无法将'String'类型的值转换为闭包结果类型'Clinica';'Any'类型的值没有成员'包含'; 将 'Any' 强制转换为 'AnyObject' 或使用 'as!' 强制向下转换为更具体的类型以访问成员;类型 'Clinica' 的值没有成员 'components')。谢谢

标签: arrays swift filter uisearchbar


【解决方案1】:

你可以试试

let searArr = searchText.lowercased().components(separatedBy: " ")
clinicsSearch = clinics.filter { item in
                                  let res  = searArr.filter { item.name.lowercased().contains($0) ||    
                                  item.specialty1.lowercased().contains($0) || 
                                  item.specialty2.lowercased().contains($0) 
                }
   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($0) ||    
                      lowSp1.contains($0) || 
                      lowSp2.contains($0) 
         }
   return !res.isEmpty
}

【讨论】:

    猜你喜欢
    • 2019-06-09
    • 2021-03-14
    • 1970-01-01
    • 2019-01-23
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多