我在获取值以进行所需组合时遇到问题。我在应用程序中使用了过滤器屏幕。我问这个问题是从问题How to put the of first and last element of Array in Swift中获得第一个元素,也是最后一个元素,但它仍然有效,但问题出在我的FiterVC
中,我首先选择了选项$400 - $600
,然后选择了{ {1}}。选择后,我将在我的currentFilter变量中获取这些值。
$200 - $400
通过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]()
方法选择值:-
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()
}
}
}
当我打印 selectedFilters 时,我得到了这些值:-
@IBAction func applyButtonAction(_ sender: UIButton) {
self.delegate?.didSelectedFilters(self, with: self.selectedFilters)
printD(self.selectedFilters)
self.dismiss(animated: true, completion: nil)
}
通过使用这种方法,我从字典中获取第一个和最后一个值,如下所示:-
currentFilters ["Price": ["$400.00 - $600.00", "$200.00 - $400.00"]]
结果是:-
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)
}
但是我真正想要的是400.00 - 400.00
。我怎样才能做到这一点。请帮忙吗?
答案 0 :(得分:0)
我认为您应该将所有相关的过滤信息存储在单独的类中。一旦以字符串形式获取它们,就应该将它们更改为适当的结构化数据。 (如果您是自己创建它们,则无论出于任何原因都不应将它们作为字符串使用)
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
}
}
现在,如果您设法获取过滤器,则通过过滤默认的一组过滤器数组来应用。你会有类似的东西。
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
现在您要做的就是将其减小到最小和最大范围。
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
答案 1 :(得分:0)
但是,有很多解决方案可以解决此问题,但是最简单,最相关的解决方案在此处突出显示:
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)
}
答案 2 :(得分:-1)
您可以使用带有函数的枚举来加载价格范围,而不是直接使用字符串。
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
}
}
}
然后,您可以使用/添加函数以获取所需的结果。
答案 3 :(得分:-2)
我们可以按部就班-
1-从字典中获取价格范围
2-遍历这些价格范围
3-用“-”分割范围,然后检查价格计数是否为2,否则这是无效的价格范围
4-从两个价格中获取数字分量,然后与之前保存的最小值和最大值进行比较,并进行相应的更新
尝试一下-
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()
}
}
答案 4 :(得分:-2)
这是您的问题的小解决方案。一切都分解为:您从过滤器中获取所有值,然后进行迭代以从中获取所有值。这样,您就可以避免比较这些对,而不必比较确切的值。
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