2017-04-21 164 views
0

基本上這是一個結構對象保持一個國家和它的端口如何過濾包含字符串和數組的結構?

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和發羅拉有兩個端口在阿爾巴尼亞

Result yielded using vlone as search string

但是所需的輸出應該只包括「vlone」,離開了所有其他端口在阿爾巴尼亞,因爲用戶是特定的與他們的查詢。

第二種情況是使用「巴塞羅那」作爲搜索關鍵字。它會返回一個包含西班牙每個港口的結果,但所需的輸出應該只包含巴塞羅那。

Results using barcelona as search key

+0

爲什麼要爲映射定義一個結構?只需使用'var countriesAndPorts = [String:[String]]()',並通過調用'let ports = countriesAndPorts [「Spain」]'來獲得一個國家的端口。 – NRitH

+0

@NRitH結構比字典好。可能有其他屬性,可能會添加邏輯,等等。 – rmaddy

+0

@NRitH我在網上看到了它,但沒有給它太多的想法。通常我使用結構來構建稍微複雜的數據結構,而不是類。 –

回答

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) 
    } 
} 

讓我們打破下來。頂層是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表示好像匹配端口列表爲空。 !否定結果。因此,如果匹配列表爲空(或portsnil),則true被否定爲false,表示沒有匹配的端口。

這兩項檢查使用標準邏輯「或」運算符||進行組合,這意味着只有兩個檢查中的一項需要爲真,以便頂級過濾器匹配該記錄。

+0

@maddy啊救生員,完美的作品。不要刻意成爲一種痛苦,但如果你可以花幾分鐘時間給我一個解決方案,那就太好了。一般來說,這些更高階的函數仍然是懸而未決的。謝謝 –

+0

我用解釋更新了我的答案。這更清楚嗎? – rmaddy

+0

感謝它更清晰。還有一件事,現在如果我搜索「倫敦」,它會引起英格蘭和南非的每個港口(顯然,在南非稱爲「東倫敦」的港口)。是否有可能只提出匹配「倫敦」的端口? –