2017-04-26 66 views
0

我有一个结构对象,它持有端口到其各自国家的映射。过滤包含字符串和字符串数组的结构对象

struct countryAndPorts { 
    var country: String? 
    var ports: [String]? 
} 

我有一个适用于每个国家对象数组var countryAndPortsArray = [countryAndPorts]()

我也有一个数组var filteredArray = [countryAndPorts]()持有过滤取决于用户的搜索查询

我与这个功能过滤countryAndPortsArraycountryAndPortsArray对象

func filteredContent(searchKey: String) { 
    filteredArray = countryAndPortsArray.filter { 
     !($0.ports?.filter{ 
      $0.range(of: searchKey, options: .caseInsensitive, range: 
      nil, locale: nil) != nil || 
      $0.localizedCaseInsensitiveCompare(searchKey) == .orderedSame 
      }.isEmpty ?? true) || 
     $0.country?.localizedCaseInsensitiveContains(searchKey) ?? true 
} 

我的问题是filteredArray结果包含内的每一个端口无论用户的搜索关键字是否与特定端口匹配,都是同一个国家。

例如,如果用户搜索“巴黎”,filteredArray将包含法国的每个端口。如果用户搜索“巴塞罗那”,filteredArray将包含西班牙的每个港口。

期望的结果应该只包含匹配“巴塞罗那”或“巴黎”的端口,而不是同一个国家内的所有其他端口。

UPDATE

使用案例:

var france = countryAndPorts(country: "France", ports: 
["monaco","paris","ajaccio","lyon"]) 

var spain = countryAndPorts(country: "Spain", ports: ["barcelona", 
"madrid", "catalan"]) 

var countryAndPortsArray = [france,spain] 

如果我搜索countryAndPortsArray巴塞罗那,它返回["barcelona", "madrid", "catalan"]。但是我希望它只是返回["barcelona"]

,这里是我的tableview代表只是柜面它揭示更多的光线,我的问题

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 
} 
+0

你能不能提供期望的结果小数据的例子。 –

+0

@OlegGordiichuk更新 –

回答

0

我写的解决方案,但它并非十全十美。但它仍然会返回预期的结果。

首先,我们可以编辑结构以获取首选结果。

struct countryAndPorts { 
    var country: String? 
    var ports: [String]? 

    func getPort(_ withName: String) -> [String]? { 
     return ports?.filter{$0.lowercased() == withName.lowercased()} 
    } 
} 

不是过滤数据的函数。这不是完美的,但它可以减少flatMap调用的数量。

func fetch(port withName: String, from ports: [countryAndPorts]) -> [String]? { 
    return ports.map{$0.getPort(withName)}.flatMap{$0}.filter{($0?.count)! > 0}.flatMap{$0}.first 
} 

结果:

fetch(port: "madrid", from: countryAndPortsArray) // ["madrid"]? 
+0

嗨,感谢您的回答。尽管我已经设法编写了一个完美的函数,但我仍然会测试你的答案并回复你。 –

+0

@Remedy_man高兴地帮助。 –

相关问题