I have a struct object holding a mapping of ports to their respective countries.
struct countryAndPorts {
var country: String?
var ports: [String]?
}
I have an array var countryAndPortsArray = [countryAndPorts]()
that holds countryAndPort
object for every country.
I also have an array var filteredArray = [countryAndPorts]()
which holds filtered countryAndPortsArray
objects depending on the user's search query
I am filtering countryAndPortsArray
with this function
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
}
My problem is the result of filteredArray
contains every port within the same country regardless the user's search key matches a particular port.
For example, if a user searches for "Paris", the filteredArray
will contain every port in France. If a user searches "barcelona", the filteredArray
will contain every port in Spain.
The desired result should only contain ports matching "barcelona" or "paris" and not every other port within the same country.
UPDATE
Use Case:
var france = countryAndPorts(country: "France", ports:
["monaco","paris","ajaccio","lyon"])
var spain = countryAndPorts(country: "Spain", ports: ["barcelona",
"madrid", "catalan"])
var countryAndPortsArray = [france,spain]
if i search countryAndPortsArray
for barcelona, it returns ["barcelona", "madrid", "catalan"]
. However i would want it to only return ["barcelona"]
here is my tableview delegates just incase it sheds more light to my question
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
}
I write solution but it is not perfect. But still it return expected result.
Firstly we could edit structure to fetch as preferred result.
struct countryAndPorts {
var country: String?
var ports: [String]?
func getPort(_ withName: String) -> [String]? {
return ports?.filter{$0.lowercased() == withName.lowercased()}
}
}
Than out function to filter data. It is not perfect but it works it is possible to reduce amount of flatMap
calls.
func fetch(port withName: String, from ports: [countryAndPorts]) -> [String]? {
return ports.map{$0.getPort(withName)}.flatMap{$0}.filter{($0?.count)! > 0}.flatMap{$0}.first
}
Result:
fetch(port: "madrid", from: countryAndPortsArray) // ["madrid"]?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.