我有一个struct对象,其中包含端口到各自国家/地区的映射。
struct countryAndPorts {
var country: String?
var ports: [String]?
}
我有一个数组var countryAndPortsArray = [countryAndPorts]()
,每个国家都有countryAndPort
个对象。
我还有一个数组var filteredArray = [countryAndPorts]()
,它根据用户的搜索查询保存已过滤的countryAndPortsArray
个对象
我正在使用此功能
过滤countryAndPortsArray
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
包含同一国家/地区内每个端口的结果,无论用户的搜索关键字与特定端口匹配。
例如,如果用户搜索“Paris”,则filteredArray
将包含法国的每个端口。如果用户搜索“barcelona”,filteredArray
将包含西班牙的每个端口。
所需结果应仅包含与“barcelona”或“paris”匹配的端口,而不包含同一国家/地区内的所有其他端口。
更新
用例:
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)
我写的解决方案但并不完美。但它仍然会返回预期的结果。
首先,我们可以编辑结构以获取作为首选结果。
struct countryAndPorts {
var country: String?
var ports: [String]?
func getPort(_ withName: String) -> [String]? {
return ports?.filter{$0.lowercased() == withName.lowercased()}
}
}
比out函数来过滤数据。它并不完美,但它可以减少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"]?