[英]How to filter a struct containing a string and an array?
基本上,這是一個包含一個國家及其港口的結構對象
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都是阿爾巴尼亞的港口
但是,所需的輸出應僅包括“ vlone”,而忽略阿爾巴尼亞的所有其他端口,因為用戶是特定於其查詢的。
第二種情況是使用“巴塞羅那”作為搜索關鍵字。 它返回一個包含西班牙每個端口的結果,但是所需的輸出應僅包含巴塞羅那。
如果要過濾數組以查找具有匹配的國家或地區的任何條目,則可以執行以下操作:
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)
}
}
讓我們分解一下。 頂層是對countryAndPortsArray
數組進行filter
的調用。 過濾器由兩部分組成。 1)檢查該國家/地區是否包含搜索文字,以及2)檢查任何端口是否包含搜索文字。
第一步檢查完成:
$0.country?.lowercased().range(of: searchKey) != nil
這是您已經擁有的部分。
第二項檢查通過以下方式完成:
!($0.ports?.filter {
$0.lowercased().range(of: searchKey) != nil
}.isEmpty ?? true)
由於ports
是一個數組,因此使用過濾器來查看是否有任何端口包含搜索文本。 isEmpty
正在檢查匹配端口的結果過濾器列表是否為空。 由於ports
是可選的,因此使用?? true
?? true
表示充當匹配端口列表為空。 !
否定結果。 因此,如果匹配列表為空(或ports
為nil
),則將true
否定為false
表示沒有匹配的端口。
使用標准邏輯“或”運算符||
兩個檢查組合在一起 這意味着對於頂層過濾器以匹配該記錄,僅需要兩項檢查中的一項為真。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.