基本上这是一个包含国家及其端口的结构对象
struct countryAndPorts {
var country: String?
var ports: [String]?
}
这些是将每个国家/地区映射到其端口的阵列。过滤后的数组应按国家/地区或端口保存过滤结果。
var countryAndPortsArray = [countryAndPorts]()
var filteredArray = [countryAndPorts]()
目前,以下功能使用国家/地区作为搜索键
成功生成过滤结果func filteredContent(searchKey: String) {
filteredArray = countryAndPortsArray.flatMap{ $0 }.filter{$0.country?.lowercased().range(of: searchKey) != nil }
}
现在我的问题是我希望通过使用端口或国家/地区作为搜索关键字来获得过滤结果。我已经尽力了,但似乎无法使用端口作为搜索键获得理想的结果。我当前的方法的改进将非常感激。 Objective-C中的答案也受到欢迎。
//Just incase it's of any use, these are my UITableView delegates
extension SearchDealsViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let count = filteredArray[section].ports?.count {
return count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if let port = filteredArray[indexPath.section].ports?[indexPath.row] {
cell.textLabel?.text = port
}
cell.textLabel?.font = UIFont.systemFont(ofSize: 10)
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
return filteredArray.count
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
portsFromTextField.text = filteredArray[indexPath.section].ports?[indexPath.row]
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableCell(withIdentifier: "header")
let tapSectionHeaderGesture = UITapGestureRecognizer(target: self, action: #selector(getCountryText(sender:)))
tapSectionHeaderGesture.numberOfTouchesRequired = 1
tapSectionHeaderGesture.numberOfTapsRequired = 1
header?.addGestureRecognizer(tapSectionHeaderGesture)
if header != nil {
header?.textLabel?.textColor = THEME_COLOUR
header?.textLabel?.font = UIFont.boldSystemFont(ofSize: 12)
header?.textLabel?.text = filteredArray[section].country
}
return header
}
func getCountryText(sender: UITapGestureRecognizer) {
if let country = sender.view as? UITableViewCell {
portsFromTextField.text = country.textLabel?.text
}
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 30
}
-------------------------------- UDPATE ----------- --------------------
此时输入“vlone”作为搜索字符串会同时返回“vlone”和“vlore”。 Vlone和Vlore都是阿尔巴尼亚的港口
Result yielded using vlone as search string
但是,所需的输出应仅包含“vlone”,并且不在阿尔巴尼亚的其他所有端口,因为用户特定于他们的查询。
第二种情况是使用“barcelona”作为搜索关键字。它返回包含西班牙每个端口的结果,但是所需的输出应该只包含Barcelona。
答案 0 :(得分:0)
如果要过滤数组以查找具有匹配国家/地区或端口的任何条目,则可以执行以下操作:
func filteredContent(searchKey: String) {
filteredArray = countryAndPortsArray.filter {
$0.country?.lowercased().range(of: searchKey) != nil ||
!($0.ports?.filter {
$0.lowercased().range(of: searchKey) != nil
}.isEmpty ?? true)
}
}
让我们打破这个局面。在顶层是filter
数组上countryAndPortsArray
的调用。过滤器由两部分组成。 1)检查国家是否包含搜索文本,以及2)检查是否有任何端口包含搜索文本。
第一次检查完成:
$0.country?.lowercased().range(of: searchKey) != nil
这是你已经拥有的部分。
第二次检查完成:
!($0.ports?.filter {
$0.lowercased().range(of: searchKey) != nil
}.isEmpty ?? true)
由于ports
是一个数组,因此使用过滤器来查看是否有任何端口包含搜索文本。 isEmpty
正在检查匹配端口的结果筛选器列表是否为空。由于ports
是可选的,因此?? true
的使用意味着就像匹配端口列表为空一样。 !
否定了结果。因此,如果匹配列表为空(或ports
为nil
),则true
将被否定为false
,表示没有匹配的端口。
使用标准逻辑"或"组合两个检查。 operator ||
表示只有两个检查中的一个必须为顶级过滤器才能匹配该记录。