[英]Filtering a struct object containing a string and array of strings
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. 我有一个数组
var countryAndPortsArray = [countryAndPorts]()
,它保存每个国家的countryAndPort
对象。
I also have an array var filteredArray = [countryAndPorts]()
which holds filtered countryAndPortsArray
objects depending on the user's search query 我还有一个数组
var filteredArray = [countryAndPorts]()
,该countryAndPortsArray
根据用户的搜索查询保存已过滤的countryAndPortsArray
对象
I am filtering countryAndPortsArray
with this function 我正在使用此功能过滤
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
}
My problem is the result of filteredArray
contains every port within the same country regardless the user's search key matches a particular port. 我的问题是,
filteredArray
的结果是包含同一个国家/地区中的每个端口,无论用户的搜索键是否匹配特定端口。
For example, if a user searches for "Paris", the filteredArray
will contain every port in France. 例如,如果用户搜索“巴黎”,则
filteredArray
将包含法国的每个端口。 If a user searches "barcelona", the filteredArray
will contain every port in Spain. 如果用户搜索“巴塞罗那”,则
filteredArray
将包含西班牙的每个端口。
The desired result should only contain ports matching "barcelona" or "paris" and not every other port within the same country. 期望的结果应仅包含与“巴塞罗那”或“巴黎”匹配的端口,而不应包含同一国家/地区中的所有其他端口。
UPDATE 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"]
. 如果我在
countryAndPortsArray
中搜索countryAndPortsArray
,则返回["barcelona", "madrid", "catalan"]
。 However i would want it to only return ["barcelona"]
但是我希望它只返回
["barcelona"]
here is my tableview delegates just incase it sheds more light to my question 这是我的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
}
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. 它不是完美的,但它可以减少
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
}
Result: 结果:
fetch(port: "madrid", from: countryAndPortsArray) // ["madrid"]?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.