簡體   English   中英

如何過濾包含字符串和數組的結構?

[英]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作為搜索字符串產生的結果

但是,所需的輸出應僅包括“ 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表示充當匹配端口列表為空。 ! 否定結果。 因此,如果匹配列表為空(或portsnil ),則將true否定為false表示沒有匹配的端口。

使用標准邏輯“或”運算符||兩個檢查組合在一起 這意味着對於頂層過濾器以匹配該記錄,僅需要兩項檢查中的一項為真。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM