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
. After selecting I am getting these values in my currentFilter variable.
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:-
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:-
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
. How can I do this. Please help?
ios arrays swift dictionary swift4
|
show 19 more comments
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
. After selecting I am getting these values in my currentFilter variable.
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:-
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:-
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
. How can I do this. Please help?
ios arrays swift dictionary swift4
Check if you are picking the correct item of the array once you split it by "-". Which items do you have in priceRange.first!.split(separator: "-") and priceRange.last!.split(separator: "-")?
– Fede Henze
Nov 21 at 8:34
1
@wings it doesn't work because you're not looking for the biggest value, you're looking for the first and the last element. These methods not aware of the values contained inside.
– inokey
Nov 21 at 8:38
1
Why don't you use a map table e.g.0 = 0-200, 1 = 200-400
etc. ? The lower value is alwaysx * 200
and the upper valuex * 200 + 200
? That avoids the annoying extraction withsplit
andreplaceOccurrences
– vadian
Nov 21 at 8:56
1
Assign tags (0-5) to the buttons. DeclarecurrentFilters
as integer arrayvar currentFilters = [Int]()
. When a filter is selected/deselected add/remove the tag to/from the array. As mentioned the lower value istag * 200
and the higher value istag * 200 + 200
.
– vadian
Nov 21 at 9:11
1
You can. It's a question of the design. I just made a suggestion to improve a very cumbersome and inefficient design.
– vadian
Nov 21 at 9:18
|
show 19 more comments
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
. After selecting I am getting these values in my currentFilter variable.
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:-
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:-
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
. How can I do this. Please help?
ios arrays swift dictionary swift4
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
. After selecting I am getting these values in my currentFilter variable.
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:-
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:-
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
. How can I do this. Please help?
ios arrays swift dictionary swift4
ios arrays swift dictionary swift4
edited Nov 21 at 9:21
asked Nov 21 at 8:22
wings
1,042422
1,042422
Check if you are picking the correct item of the array once you split it by "-". Which items do you have in priceRange.first!.split(separator: "-") and priceRange.last!.split(separator: "-")?
– Fede Henze
Nov 21 at 8:34
1
@wings it doesn't work because you're not looking for the biggest value, you're looking for the first and the last element. These methods not aware of the values contained inside.
– inokey
Nov 21 at 8:38
1
Why don't you use a map table e.g.0 = 0-200, 1 = 200-400
etc. ? The lower value is alwaysx * 200
and the upper valuex * 200 + 200
? That avoids the annoying extraction withsplit
andreplaceOccurrences
– vadian
Nov 21 at 8:56
1
Assign tags (0-5) to the buttons. DeclarecurrentFilters
as integer arrayvar currentFilters = [Int]()
. When a filter is selected/deselected add/remove the tag to/from the array. As mentioned the lower value istag * 200
and the higher value istag * 200 + 200
.
– vadian
Nov 21 at 9:11
1
You can. It's a question of the design. I just made a suggestion to improve a very cumbersome and inefficient design.
– vadian
Nov 21 at 9:18
|
show 19 more comments
Check if you are picking the correct item of the array once you split it by "-". Which items do you have in priceRange.first!.split(separator: "-") and priceRange.last!.split(separator: "-")?
– Fede Henze
Nov 21 at 8:34
1
@wings it doesn't work because you're not looking for the biggest value, you're looking for the first and the last element. These methods not aware of the values contained inside.
– inokey
Nov 21 at 8:38
1
Why don't you use a map table e.g.0 = 0-200, 1 = 200-400
etc. ? The lower value is alwaysx * 200
and the upper valuex * 200 + 200
? That avoids the annoying extraction withsplit
andreplaceOccurrences
– vadian
Nov 21 at 8:56
1
Assign tags (0-5) to the buttons. DeclarecurrentFilters
as integer arrayvar currentFilters = [Int]()
. When a filter is selected/deselected add/remove the tag to/from the array. As mentioned the lower value istag * 200
and the higher value istag * 200 + 200
.
– vadian
Nov 21 at 9:11
1
You can. It's a question of the design. I just made a suggestion to improve a very cumbersome and inefficient design.
– vadian
Nov 21 at 9:18
Check if you are picking the correct item of the array once you split it by "-". Which items do you have in priceRange.first!.split(separator: "-") and priceRange.last!.split(separator: "-")?
– Fede Henze
Nov 21 at 8:34
Check if you are picking the correct item of the array once you split it by "-". Which items do you have in priceRange.first!.split(separator: "-") and priceRange.last!.split(separator: "-")?
– Fede Henze
Nov 21 at 8:34
1
1
@wings it doesn't work because you're not looking for the biggest value, you're looking for the first and the last element. These methods not aware of the values contained inside.
– inokey
Nov 21 at 8:38
@wings it doesn't work because you're not looking for the biggest value, you're looking for the first and the last element. These methods not aware of the values contained inside.
– inokey
Nov 21 at 8:38
1
1
Why don't you use a map table e.g.
0 = 0-200, 1 = 200-400
etc. ? The lower value is always x * 200
and the upper value x * 200 + 200
? That avoids the annoying extraction with split
and replaceOccurrences
– vadian
Nov 21 at 8:56
Why don't you use a map table e.g.
0 = 0-200, 1 = 200-400
etc. ? The lower value is always x * 200
and the upper value x * 200 + 200
? That avoids the annoying extraction with split
and replaceOccurrences
– vadian
Nov 21 at 8:56
1
1
Assign tags (0-5) to the buttons. Declare
currentFilters
as integer array var currentFilters = [Int]()
. When a filter is selected/deselected add/remove the tag to/from the array. As mentioned the lower value is tag * 200
and the higher value is tag * 200 + 200
.– vadian
Nov 21 at 9:11
Assign tags (0-5) to the buttons. Declare
currentFilters
as integer array var currentFilters = [Int]()
. When a filter is selected/deselected add/remove the tag to/from the array. As mentioned the lower value is tag * 200
and the higher value is tag * 200 + 200
.– vadian
Nov 21 at 9:11
1
1
You can. It's a question of the design. I just made a suggestion to improve a very cumbersome and inefficient design.
– vadian
Nov 21 at 9:18
You can. It's a question of the design. I just made a suggestion to improve a very cumbersome and inefficient design.
– vadian
Nov 21 at 9:18
|
show 19 more comments
5 Answers
5
active
oldest
votes
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)
}
This is wrong. Yourmin
is anInt
by declaration, you complier will throw an error at if statement line.
– inokey
Nov 21 at 9:29
Updated the answer. It will work fine now.
– nikksindia
Nov 21 at 9:33
Prices areDouble
, notInt
– inokey
Nov 21 at 9:34
@inokey : cast it to Double type instead
– nikksindia
Nov 21 at 9:35
add a comment |
In my opinion you should be storing all the relevant filtering information in separate classes. You should change them to proper structured data as soon as you get them as strings. (If you are creating them yourself, then you shouldn't be having them as strings for any reason)
class PriceRange {
var minValue: Int
var maxValue: Int
init(_ minValue: Int, _ maxValue: Int) {
self.minValue = minValue
self.maxValue = maxValue
}
}
class ProductRating { // Relevant naming
// Relevant parameters
}
class Arriving { // Relevant naming
// Relevant parameters
}
// The class whose object which store the filtered information
class Filters {
var priceRange: [PriceRange]
var productRating: [ProductRating] // Change as necessary
var arriving: [Arriving] // Change as necessary
init(priceRange: [PriceRange], productRating: [ProductRating], arriving: [Arriving]) {
self.priceRange = priceRange
self.productRating = productRating
self.arriving = arriving
}
}
Now if you manage to get the filtersApplied by filtering the default set of array of filters. You would have something like this.
var filteredPriceRanges = [PriceRange(400, 600), PriceRange(200, 400)] // Example
var filtersApplied = Filters(priceRange: filteredPriceRanges, productRating: /* filtered product rating */, arriving: /* filtered arriving information */)
let selectedRanges = filtersApplied.priceRange
Now all you need to do is reduce it to the minimum and maximum range.
let finalRange = selectedRanges.reduce(PriceRange(selectedRanges.first?.minValue ?? 0, selectedRanges.first?.maxValue ?? 0)) { (result, range) -> PriceRange in
if result.minValue > range.minValue {
result.minValue = range.minValue
}
if result.maxValue < range.maxValue {
result.maxValue = range.maxValue
}
return result
}
// Note this returns (0, 0) if none of the filters are selected. So make sure you have some way of enforcing the use has atleast one filter selected
What will happen if user doesn't selected any value ?
– wings
Nov 21 at 9:14
@wings read the last comment. Btw what happens now?
– Rakesha Shastri
Nov 21 at 9:15
Can I show I am getting this filter values from variable So you can understand better what actually is going
– wings
Nov 21 at 9:17
@wings sure, go ahead.
– Rakesha Shastri
Nov 21 at 9:18
Updated Sir Please check
– wings
Nov 21 at 9:22
|
show 15 more comments
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.
Price ranges will be dynamic and may not be multiple of 200
– Aakash
Nov 21 at 9:02
add a comment |
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
it won't work, by comparing string value means $1000.00 will be smaller than $400.00.
– koropok
Nov 21 at 8:54
@koropok fair point, will update the answer!
– inokey
Nov 21 at 8:56
@inokey pls don't force unwrap this cause crashes in some situations
– Aakash
Nov 21 at 10:03
add a comment |
We can do by steps -
1 - Get the price ranges from the dictionary
2 - Iterate over those price ranges
3 - Split the range by "-" and check if the prices count is 2 else this is an invalid price range
4 - Get the numeric components from the two prices and then compare from the previously saved min and max values and update them accordingly
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()
}
}
Sir explain your answer please
– wings
Nov 21 at 9:43
okay i am adding more info to the answer
– Aakash
Nov 21 at 9:47
Yes that will be the cause of down votes
– wings
Nov 21 at 9:48
@wings I have updated the answer, let me know in case you need more info
– Aakash
Nov 21 at 10:11
Okay I will check it now
– wings
Nov 21 at 10:14
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53407834%2fhow-to-get-the-lowest-and-highest-value-from-dictionary-in-swift%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
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)
}
This is wrong. Yourmin
is anInt
by declaration, you complier will throw an error at if statement line.
– inokey
Nov 21 at 9:29
Updated the answer. It will work fine now.
– nikksindia
Nov 21 at 9:33
Prices areDouble
, notInt
– inokey
Nov 21 at 9:34
@inokey : cast it to Double type instead
– nikksindia
Nov 21 at 9:35
add a comment |
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)
}
This is wrong. Yourmin
is anInt
by declaration, you complier will throw an error at if statement line.
– inokey
Nov 21 at 9:29
Updated the answer. It will work fine now.
– nikksindia
Nov 21 at 9:33
Prices areDouble
, notInt
– inokey
Nov 21 at 9:34
@inokey : cast it to Double type instead
– nikksindia
Nov 21 at 9:35
add a comment |
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)
}
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)
}
edited Nov 21 at 9:33
answered Nov 21 at 9:09
nikksindia
385210
385210
This is wrong. Yourmin
is anInt
by declaration, you complier will throw an error at if statement line.
– inokey
Nov 21 at 9:29
Updated the answer. It will work fine now.
– nikksindia
Nov 21 at 9:33
Prices areDouble
, notInt
– inokey
Nov 21 at 9:34
@inokey : cast it to Double type instead
– nikksindia
Nov 21 at 9:35
add a comment |
This is wrong. Yourmin
is anInt
by declaration, you complier will throw an error at if statement line.
– inokey
Nov 21 at 9:29
Updated the answer. It will work fine now.
– nikksindia
Nov 21 at 9:33
Prices areDouble
, notInt
– inokey
Nov 21 at 9:34
@inokey : cast it to Double type instead
– nikksindia
Nov 21 at 9:35
This is wrong. Your
min
is an Int
by declaration, you complier will throw an error at if statement line.– inokey
Nov 21 at 9:29
This is wrong. Your
min
is an Int
by declaration, you complier will throw an error at if statement line.– inokey
Nov 21 at 9:29
Updated the answer. It will work fine now.
– nikksindia
Nov 21 at 9:33
Updated the answer. It will work fine now.
– nikksindia
Nov 21 at 9:33
Prices are
Double
, not Int
– inokey
Nov 21 at 9:34
Prices are
Double
, not Int
– inokey
Nov 21 at 9:34
@inokey : cast it to Double type instead
– nikksindia
Nov 21 at 9:35
@inokey : cast it to Double type instead
– nikksindia
Nov 21 at 9:35
add a comment |
In my opinion you should be storing all the relevant filtering information in separate classes. You should change them to proper structured data as soon as you get them as strings. (If you are creating them yourself, then you shouldn't be having them as strings for any reason)
class PriceRange {
var minValue: Int
var maxValue: Int
init(_ minValue: Int, _ maxValue: Int) {
self.minValue = minValue
self.maxValue = maxValue
}
}
class ProductRating { // Relevant naming
// Relevant parameters
}
class Arriving { // Relevant naming
// Relevant parameters
}
// The class whose object which store the filtered information
class Filters {
var priceRange: [PriceRange]
var productRating: [ProductRating] // Change as necessary
var arriving: [Arriving] // Change as necessary
init(priceRange: [PriceRange], productRating: [ProductRating], arriving: [Arriving]) {
self.priceRange = priceRange
self.productRating = productRating
self.arriving = arriving
}
}
Now if you manage to get the filtersApplied by filtering the default set of array of filters. You would have something like this.
var filteredPriceRanges = [PriceRange(400, 600), PriceRange(200, 400)] // Example
var filtersApplied = Filters(priceRange: filteredPriceRanges, productRating: /* filtered product rating */, arriving: /* filtered arriving information */)
let selectedRanges = filtersApplied.priceRange
Now all you need to do is reduce it to the minimum and maximum range.
let finalRange = selectedRanges.reduce(PriceRange(selectedRanges.first?.minValue ?? 0, selectedRanges.first?.maxValue ?? 0)) { (result, range) -> PriceRange in
if result.minValue > range.minValue {
result.minValue = range.minValue
}
if result.maxValue < range.maxValue {
result.maxValue = range.maxValue
}
return result
}
// Note this returns (0, 0) if none of the filters are selected. So make sure you have some way of enforcing the use has atleast one filter selected
What will happen if user doesn't selected any value ?
– wings
Nov 21 at 9:14
@wings read the last comment. Btw what happens now?
– Rakesha Shastri
Nov 21 at 9:15
Can I show I am getting this filter values from variable So you can understand better what actually is going
– wings
Nov 21 at 9:17
@wings sure, go ahead.
– Rakesha Shastri
Nov 21 at 9:18
Updated Sir Please check
– wings
Nov 21 at 9:22
|
show 15 more comments
In my opinion you should be storing all the relevant filtering information in separate classes. You should change them to proper structured data as soon as you get them as strings. (If you are creating them yourself, then you shouldn't be having them as strings for any reason)
class PriceRange {
var minValue: Int
var maxValue: Int
init(_ minValue: Int, _ maxValue: Int) {
self.minValue = minValue
self.maxValue = maxValue
}
}
class ProductRating { // Relevant naming
// Relevant parameters
}
class Arriving { // Relevant naming
// Relevant parameters
}
// The class whose object which store the filtered information
class Filters {
var priceRange: [PriceRange]
var productRating: [ProductRating] // Change as necessary
var arriving: [Arriving] // Change as necessary
init(priceRange: [PriceRange], productRating: [ProductRating], arriving: [Arriving]) {
self.priceRange = priceRange
self.productRating = productRating
self.arriving = arriving
}
}
Now if you manage to get the filtersApplied by filtering the default set of array of filters. You would have something like this.
var filteredPriceRanges = [PriceRange(400, 600), PriceRange(200, 400)] // Example
var filtersApplied = Filters(priceRange: filteredPriceRanges, productRating: /* filtered product rating */, arriving: /* filtered arriving information */)
let selectedRanges = filtersApplied.priceRange
Now all you need to do is reduce it to the minimum and maximum range.
let finalRange = selectedRanges.reduce(PriceRange(selectedRanges.first?.minValue ?? 0, selectedRanges.first?.maxValue ?? 0)) { (result, range) -> PriceRange in
if result.minValue > range.minValue {
result.minValue = range.minValue
}
if result.maxValue < range.maxValue {
result.maxValue = range.maxValue
}
return result
}
// Note this returns (0, 0) if none of the filters are selected. So make sure you have some way of enforcing the use has atleast one filter selected
What will happen if user doesn't selected any value ?
– wings
Nov 21 at 9:14
@wings read the last comment. Btw what happens now?
– Rakesha Shastri
Nov 21 at 9:15
Can I show I am getting this filter values from variable So you can understand better what actually is going
– wings
Nov 21 at 9:17
@wings sure, go ahead.
– Rakesha Shastri
Nov 21 at 9:18
Updated Sir Please check
– wings
Nov 21 at 9:22
|
show 15 more comments
In my opinion you should be storing all the relevant filtering information in separate classes. You should change them to proper structured data as soon as you get them as strings. (If you are creating them yourself, then you shouldn't be having them as strings for any reason)
class PriceRange {
var minValue: Int
var maxValue: Int
init(_ minValue: Int, _ maxValue: Int) {
self.minValue = minValue
self.maxValue = maxValue
}
}
class ProductRating { // Relevant naming
// Relevant parameters
}
class Arriving { // Relevant naming
// Relevant parameters
}
// The class whose object which store the filtered information
class Filters {
var priceRange: [PriceRange]
var productRating: [ProductRating] // Change as necessary
var arriving: [Arriving] // Change as necessary
init(priceRange: [PriceRange], productRating: [ProductRating], arriving: [Arriving]) {
self.priceRange = priceRange
self.productRating = productRating
self.arriving = arriving
}
}
Now if you manage to get the filtersApplied by filtering the default set of array of filters. You would have something like this.
var filteredPriceRanges = [PriceRange(400, 600), PriceRange(200, 400)] // Example
var filtersApplied = Filters(priceRange: filteredPriceRanges, productRating: /* filtered product rating */, arriving: /* filtered arriving information */)
let selectedRanges = filtersApplied.priceRange
Now all you need to do is reduce it to the minimum and maximum range.
let finalRange = selectedRanges.reduce(PriceRange(selectedRanges.first?.minValue ?? 0, selectedRanges.first?.maxValue ?? 0)) { (result, range) -> PriceRange in
if result.minValue > range.minValue {
result.minValue = range.minValue
}
if result.maxValue < range.maxValue {
result.maxValue = range.maxValue
}
return result
}
// Note this returns (0, 0) if none of the filters are selected. So make sure you have some way of enforcing the use has atleast one filter selected
In my opinion you should be storing all the relevant filtering information in separate classes. You should change them to proper structured data as soon as you get them as strings. (If you are creating them yourself, then you shouldn't be having them as strings for any reason)
class PriceRange {
var minValue: Int
var maxValue: Int
init(_ minValue: Int, _ maxValue: Int) {
self.minValue = minValue
self.maxValue = maxValue
}
}
class ProductRating { // Relevant naming
// Relevant parameters
}
class Arriving { // Relevant naming
// Relevant parameters
}
// The class whose object which store the filtered information
class Filters {
var priceRange: [PriceRange]
var productRating: [ProductRating] // Change as necessary
var arriving: [Arriving] // Change as necessary
init(priceRange: [PriceRange], productRating: [ProductRating], arriving: [Arriving]) {
self.priceRange = priceRange
self.productRating = productRating
self.arriving = arriving
}
}
Now if you manage to get the filtersApplied by filtering the default set of array of filters. You would have something like this.
var filteredPriceRanges = [PriceRange(400, 600), PriceRange(200, 400)] // Example
var filtersApplied = Filters(priceRange: filteredPriceRanges, productRating: /* filtered product rating */, arriving: /* filtered arriving information */)
let selectedRanges = filtersApplied.priceRange
Now all you need to do is reduce it to the minimum and maximum range.
let finalRange = selectedRanges.reduce(PriceRange(selectedRanges.first?.minValue ?? 0, selectedRanges.first?.maxValue ?? 0)) { (result, range) -> PriceRange in
if result.minValue > range.minValue {
result.minValue = range.minValue
}
if result.maxValue < range.maxValue {
result.maxValue = range.maxValue
}
return result
}
// Note this returns (0, 0) if none of the filters are selected. So make sure you have some way of enforcing the use has atleast one filter selected
edited Nov 21 at 9:46
answered Nov 21 at 9:06
Rakesha Shastri
6,83421232
6,83421232
What will happen if user doesn't selected any value ?
– wings
Nov 21 at 9:14
@wings read the last comment. Btw what happens now?
– Rakesha Shastri
Nov 21 at 9:15
Can I show I am getting this filter values from variable So you can understand better what actually is going
– wings
Nov 21 at 9:17
@wings sure, go ahead.
– Rakesha Shastri
Nov 21 at 9:18
Updated Sir Please check
– wings
Nov 21 at 9:22
|
show 15 more comments
What will happen if user doesn't selected any value ?
– wings
Nov 21 at 9:14
@wings read the last comment. Btw what happens now?
– Rakesha Shastri
Nov 21 at 9:15
Can I show I am getting this filter values from variable So you can understand better what actually is going
– wings
Nov 21 at 9:17
@wings sure, go ahead.
– Rakesha Shastri
Nov 21 at 9:18
Updated Sir Please check
– wings
Nov 21 at 9:22
What will happen if user doesn't selected any value ?
– wings
Nov 21 at 9:14
What will happen if user doesn't selected any value ?
– wings
Nov 21 at 9:14
@wings read the last comment. Btw what happens now?
– Rakesha Shastri
Nov 21 at 9:15
@wings read the last comment. Btw what happens now?
– Rakesha Shastri
Nov 21 at 9:15
Can I show I am getting this filter values from variable So you can understand better what actually is going
– wings
Nov 21 at 9:17
Can I show I am getting this filter values from variable So you can understand better what actually is going
– wings
Nov 21 at 9:17
@wings sure, go ahead.
– Rakesha Shastri
Nov 21 at 9:18
@wings sure, go ahead.
– Rakesha Shastri
Nov 21 at 9:18
Updated Sir Please check
– wings
Nov 21 at 9:22
Updated Sir Please check
– wings
Nov 21 at 9:22
|
show 15 more comments
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.
Price ranges will be dynamic and may not be multiple of 200
– Aakash
Nov 21 at 9:02
add a comment |
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.
Price ranges will be dynamic and may not be multiple of 200
– Aakash
Nov 21 at 9:02
add a comment |
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.
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.
answered Nov 21 at 9:01
Fede Henze
505615
505615
Price ranges will be dynamic and may not be multiple of 200
– Aakash
Nov 21 at 9:02
add a comment |
Price ranges will be dynamic and may not be multiple of 200
– Aakash
Nov 21 at 9:02
Price ranges will be dynamic and may not be multiple of 200
– Aakash
Nov 21 at 9:02
Price ranges will be dynamic and may not be multiple of 200
– Aakash
Nov 21 at 9:02
add a comment |
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
it won't work, by comparing string value means $1000.00 will be smaller than $400.00.
– koropok
Nov 21 at 8:54
@koropok fair point, will update the answer!
– inokey
Nov 21 at 8:56
@inokey pls don't force unwrap this cause crashes in some situations
– Aakash
Nov 21 at 10:03
add a comment |
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
it won't work, by comparing string value means $1000.00 will be smaller than $400.00.
– koropok
Nov 21 at 8:54
@koropok fair point, will update the answer!
– inokey
Nov 21 at 8:56
@inokey pls don't force unwrap this cause crashes in some situations
– Aakash
Nov 21 at 10:03
add a comment |
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
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
edited Nov 21 at 9:35
answered Nov 21 at 8:49
inokey
1,070617
1,070617
it won't work, by comparing string value means $1000.00 will be smaller than $400.00.
– koropok
Nov 21 at 8:54
@koropok fair point, will update the answer!
– inokey
Nov 21 at 8:56
@inokey pls don't force unwrap this cause crashes in some situations
– Aakash
Nov 21 at 10:03
add a comment |
it won't work, by comparing string value means $1000.00 will be smaller than $400.00.
– koropok
Nov 21 at 8:54
@koropok fair point, will update the answer!
– inokey
Nov 21 at 8:56
@inokey pls don't force unwrap this cause crashes in some situations
– Aakash
Nov 21 at 10:03
it won't work, by comparing string value means $1000.00 will be smaller than $400.00.
– koropok
Nov 21 at 8:54
it won't work, by comparing string value means $1000.00 will be smaller than $400.00.
– koropok
Nov 21 at 8:54
@koropok fair point, will update the answer!
– inokey
Nov 21 at 8:56
@koropok fair point, will update the answer!
– inokey
Nov 21 at 8:56
@inokey pls don't force unwrap this cause crashes in some situations
– Aakash
Nov 21 at 10:03
@inokey pls don't force unwrap this cause crashes in some situations
– Aakash
Nov 21 at 10:03
add a comment |
We can do by steps -
1 - Get the price ranges from the dictionary
2 - Iterate over those price ranges
3 - Split the range by "-" and check if the prices count is 2 else this is an invalid price range
4 - Get the numeric components from the two prices and then compare from the previously saved min and max values and update them accordingly
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()
}
}
Sir explain your answer please
– wings
Nov 21 at 9:43
okay i am adding more info to the answer
– Aakash
Nov 21 at 9:47
Yes that will be the cause of down votes
– wings
Nov 21 at 9:48
@wings I have updated the answer, let me know in case you need more info
– Aakash
Nov 21 at 10:11
Okay I will check it now
– wings
Nov 21 at 10:14
add a comment |
We can do by steps -
1 - Get the price ranges from the dictionary
2 - Iterate over those price ranges
3 - Split the range by "-" and check if the prices count is 2 else this is an invalid price range
4 - Get the numeric components from the two prices and then compare from the previously saved min and max values and update them accordingly
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()
}
}
Sir explain your answer please
– wings
Nov 21 at 9:43
okay i am adding more info to the answer
– Aakash
Nov 21 at 9:47
Yes that will be the cause of down votes
– wings
Nov 21 at 9:48
@wings I have updated the answer, let me know in case you need more info
– Aakash
Nov 21 at 10:11
Okay I will check it now
– wings
Nov 21 at 10:14
add a comment |
We can do by steps -
1 - Get the price ranges from the dictionary
2 - Iterate over those price ranges
3 - Split the range by "-" and check if the prices count is 2 else this is an invalid price range
4 - Get the numeric components from the two prices and then compare from the previously saved min and max values and update them accordingly
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()
}
}
We can do by steps -
1 - Get the price ranges from the dictionary
2 - Iterate over those price ranges
3 - Split the range by "-" and check if the prices count is 2 else this is an invalid price range
4 - Get the numeric components from the two prices and then compare from the previously saved min and max values and update them accordingly
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()
}
}
edited Nov 21 at 10:10
answered Nov 21 at 8:39
Aakash
1,338715
1,338715
Sir explain your answer please
– wings
Nov 21 at 9:43
okay i am adding more info to the answer
– Aakash
Nov 21 at 9:47
Yes that will be the cause of down votes
– wings
Nov 21 at 9:48
@wings I have updated the answer, let me know in case you need more info
– Aakash
Nov 21 at 10:11
Okay I will check it now
– wings
Nov 21 at 10:14
add a comment |
Sir explain your answer please
– wings
Nov 21 at 9:43
okay i am adding more info to the answer
– Aakash
Nov 21 at 9:47
Yes that will be the cause of down votes
– wings
Nov 21 at 9:48
@wings I have updated the answer, let me know in case you need more info
– Aakash
Nov 21 at 10:11
Okay I will check it now
– wings
Nov 21 at 10:14
Sir explain your answer please
– wings
Nov 21 at 9:43
Sir explain your answer please
– wings
Nov 21 at 9:43
okay i am adding more info to the answer
– Aakash
Nov 21 at 9:47
okay i am adding more info to the answer
– Aakash
Nov 21 at 9:47
Yes that will be the cause of down votes
– wings
Nov 21 at 9:48
Yes that will be the cause of down votes
– wings
Nov 21 at 9:48
@wings I have updated the answer, let me know in case you need more info
– Aakash
Nov 21 at 10:11
@wings I have updated the answer, let me know in case you need more info
– Aakash
Nov 21 at 10:11
Okay I will check it now
– wings
Nov 21 at 10:14
Okay I will check it now
– wings
Nov 21 at 10:14
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53407834%2fhow-to-get-the-lowest-and-highest-value-from-dictionary-in-swift%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Check if you are picking the correct item of the array once you split it by "-". Which items do you have in priceRange.first!.split(separator: "-") and priceRange.last!.split(separator: "-")?
– Fede Henze
Nov 21 at 8:34
1
@wings it doesn't work because you're not looking for the biggest value, you're looking for the first and the last element. These methods not aware of the values contained inside.
– inokey
Nov 21 at 8:38
1
Why don't you use a map table e.g.
0 = 0-200, 1 = 200-400
etc. ? The lower value is alwaysx * 200
and the upper valuex * 200 + 200
? That avoids the annoying extraction withsplit
andreplaceOccurrences
– vadian
Nov 21 at 8:56
1
Assign tags (0-5) to the buttons. Declare
currentFilters
as integer arrayvar currentFilters = [Int]()
. When a filter is selected/deselected add/remove the tag to/from the array. As mentioned the lower value istag * 200
and the higher value istag * 200 + 200
.– vadian
Nov 21 at 9:11
1
You can. It's a question of the design. I just made a suggestion to improve a very cumbersome and inefficient design.
– vadian
Nov 21 at 9:18