[英]How to get the Lowest and Highest Value from Dictionary in Swift
I am facing a problem in getting the values to make the desired combination. 我在获取值以进行所需组合时遇到问题。 I am using a filter screen in my app.
我在应用程序中使用了过滤器屏幕。 I asked this question to get the first and last element from the question How to put the of first and last element of Array in Swift and it is working but the problem is in my
FiterVC
first I selected the option $400 - $600
and then I selected the $200 - $400
. 我问了这个问题,从问题中获取第一个和最后一个元素。 如何将数组的第一个和最后一个元素放入Swift中 ,它正在工作,但问题出在我的
FiterVC
中,我首先选择了$400 - $600
选项,然后选择了$200 - $400
。 After selecting I am getting these values in my currentFilter variable. 选择后,我将在我的currentFilter变量中获取这些值。
private let menus = [
["title": "Price", "isMultiSelection": true, "values": [
["title": "$00.00 - $200.00"],
["title": "$200.00 - $400.00"],
["title": "$400.00 - $600.00"],
["title": "$600.00 - $800.00"],
["title": "$800.00 - $1000.00"],
]],
["title": "Product Rating", "isMultiSelection": true, "values": [
["title": "5"],
["title": "4"],
["title": "3"],
["title": "2"],
["title": "1"]
]],
["title": "Arriving", "isMultiSelection": true, "values": [
["title": "New Arrivials"],
["title": "Coming Soon"]
]]
]
private var currentFilters = [String:Any]()
Selecting values in didSelect
method:- 在
didSelect
方法中选择值:-
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView === self.menuTableView {
self.currentSelectedMenu = indexPath.row
self.menuTableView.reloadData()
self.valueTableView.reloadData()
}
else {
if let title = self.menus[self.currentSelectedMenu]["title"] as? String, let values = self.menus[self.currentSelectedMenu]["values"] as? [[String:Any]], let obj = values[indexPath.row]["title"] as? String {
if let old = self.selectedFilters[title] as? [String], let isAllowedMulti = self.menus[self.currentSelectedMenu]["isMultiSelection"] as? Bool, !old.isEmpty, !isAllowedMulti {
var temp = old
if old.contains(obj), let index = old.index(of: obj) {
temp.remove(at: index)
}
else {
temp.append(obj)
}
self.selectedFilters[title] = temp
}
else {
self.selectedFilters[title] = [obj]
}
self.valueTableView.reloadData()
}
}
}
And on Apply button click:- 然后在“应用”按钮上单击:-
@IBAction func applyButtonAction(_ sender: UIButton) {
self.delegate?.didSelectedFilters(self, with: self.selectedFilters)
printD(self.selectedFilters)
self.dismiss(animated: true, completion: nil)
}
When I am printing the selectedFilters I am getting these values:- 当我打印selectedFilters时,我得到了这些值:
currentFilters ["Price": ["$400.00 - $600.00", "$200.00 - $400.00"]]
And by using this method I am getting the first and last value from dictionary like this:- 通过使用这种方法,我可以从字典中获取第一个和最后一个值,如下所示:
if let obj = currentFilters["Price"] as? [String] {
self.priceRange = obj
printD(self.priceRange)
let first = priceRange.first!.split(separator: "-").first!
let last = priceRange.last!.split(separator: "-").last!
let str = "\(first)-\(last)"
let str2 = str.replacingOccurrences(of: "$", with: "", options: NSString.CompareOptions.literal, range: nil)
newPrice = str2
printD(newPrice)
}
The result is :- 其结果是:-
400.00 - 400.00
but what I actually want is 200 - 600
. 但是我真正想要的是
200 - 600
。 How can I do this. 我怎样才能做到这一点。 Please help?
请帮忙?
However there are many solutions available to this problem but simplest and most relevant solution is highlighted here: 但是,有许多解决方案可用于解决此问题,但此处重点介绍了最简单,最相关的解决方案:
let min = 1000, max = 0
if let obj = currentFilters["Price"] as? [String] {
self.priceRange = obj
printD(self.priceRange)
for str in obj{
let first = str.split(separator: "-").first!.replacingOccurrences(of: "$", with: "", options:
NSString.CompareOptions.literal, range: nil)
let last = str.split(separator: "-").last!.replacingOccurrences(of: "$", with: "", options:
NSString.CompareOptions.literal, range: nil)
if Int(first) < min{
min = first
}
if Int(last) > max{
max = last
}
}
let str = "\(min)-\(max)"
newPrice = str
printD(newPrice)
}
You can use an enum with functions to load your prices ranges instead of using directly Strings. 您可以使用带有函数的枚举来加载价格范围,而不是直接使用字符串。
enum PriceRange: String {
case
low = "200 - 400",
high = "400 - 600"
static let priceRanges = [low, high]
func getStringValue() -> String {
return self.rawValue
}
func getMinValueForRange(stringRange: String) -> Int? {
switch stringRange {
case "200 - 400":
return 200;
case "400 - 600":
return 400;
default:
return nil
}
}
func getMaxValueForRange(stringRange: String) -> Int? {
switch stringRange {
case "200 - 400":
return 400;
case "400 - 600":
return 600;
default:
return nil
}
}
}
Then you can use/add functions to get the result that you are looking for. 然后,您可以使用/添加函数以获取所需的结果。
We can do by steps - 我们可以循序渐进-
1 - Get the price ranges from the dictionary 1-从字典中获取价格范围
2 - Iterate over those price ranges 2-遍历这些价格范围
3 - Split the range by "-" and check if the prices count is 2 else this is an invalid price range 3-用“-”分隔范围,然后检查价格计数是否为2,否则这是无效的价格范围
4 - Get the numeric components from the two prices and then compare from the previously saved min and max values and update them accordingly 4-从两个价格中获取数字成分,然后与之前保存的最小和最大值进行比较,并进行相应的更新
Try this - 尝试这个 -
if let priceRanges = currentFilters["Price"] as? [String] { // Extract the price ranges from dictionary
var minValue: Double? // Holds the min value
var maxValue: Double? // Holds the max value
for priceRange in priceRanges { Iterate over the price ranges
let prices = priceRange.split(separator: "-") // Separate price range by "-"
guard prices.count == 2 else { // Checks if there are 2 prices else price range is invalid
print("invalid price range")
continue // skip this price range when invalid
}
let firstPrice = String(prices[0]).numericString // Extract numerics from the first price
let secondPrice = String(prices[1]).numericString // Same for the second price
if let value = Double(firstPrice) { // Check if the price is valid amount by casting it to double
if let mValue = minValue { // Check if we have earlier saved a minValue from a price range
minValue = min(mValue, value) // Assign minimum of current price and earlier save min price
} else {
minValue = value // Else just save this price to minValue
}
}
if let value = Double(secondPrice) { // Check if the price is valid amount by casting it to double
if let mValue = maxValue { // Check if we have earlier saved a maxValue from a price range
maxValue = max(mValue, value) // Assign maximum of current price and earlier save max price
} else {
maxValue = value // Else just save this price to maxValue
}
}
}
if let minV = minValue, let maxV = maxValue { // Check if we have a min and max value from the price ranges
print("\(minV) - \(maxV)")
} else {
print("unable to find desired price range") // Else print this error message
}
}
extension String {
/// Returns a string with all non-numeric characters removed
public var numericString: String {
let characterSet = CharacterSet(charactersIn: "01234567890.").inverted
return components(separatedBy: characterSet)
.joined()
}
}
Here's the small solution of your problem. 这是您的问题的小解决方案。 It all breaks down to that: you get all the values from your filters, and then iterating over getting all the values from it.
一切都分解为:您从过滤器中获取所有值,然后进行迭代以从中获取所有值。 That way you avoid comparing the pairs and instead comparing the exact values.
这样,您就可以避免比较这些对,而不必比较确切的值。
let currentFilters = ["Price": ["$400.00 - $600.00", "$200.00 - $400.00"]]
let ranges = currentFilters["Price"]!
var values: [Double] = []
ranges.forEach { range in // iterate over each range
let rangeValues = range.split(separator: "-")
for value in rangeValues { // iterate over each value in range
values.append(Double( // cast string value to Double
String(value)
.replacingOccurrences(of: " ", with: "")
.replacingOccurrences(of: "$", with: "")
)!)
}
}
let min = values.min() // prints 200
let max = values.max() // prints 600
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.