【问题标题】:Swift - Sorting array of dollar valuesSwift - 对美元值数组进行排序
【发布时间】:2015-04-17 19:30:08
【问题描述】:

我有一个格式如下的交易数组:

“$2.25 饮料 A”

“$5 饮料 B”

“$10 饮料 C”

我想按金额对它们进行排序。

    deals.sort {
        var first = $0.deal as String
        var second = $1.deal as String

        var myArr1 = first.componentsSeparatedByString(" ")
        var myArr2 = second.componentsSeparatedByString(" ")

        var formatter = NSNumberFormatter()
        formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle

        if let price1 = formatter.numberFromString(myArr1[0]) as NSNumber! {
            if let price2 = formatter.numberFromString(myArr2[0]) as NSNumber!{
                return first < second
            }
        }
        return false
    }

这适用于像 $4.25 和任何一位数的值。如果我尝试 10.25 美元之类的东西,它就不能正确排序。

这是我正在使用测试代码的游乐场

import UIKit


var deals: [(deal:String, bar:String)] = []

deals.append(deal: "$0.95" as String, bar: "bar" as String)
deals.append(deal: "$2.95" as String, bar: "bar" as String)
deals.append(deal: "$11.95" as String, bar: "bar" as String)
deals.append(deal: "$3.95" as String, bar: "bar" as String)


deals.sort {
    var first = $0.deal as String
    var second = $1.deal as String

    var myArr1 = first.componentsSeparatedByString(" ")
    var myArr2 = second.componentsSeparatedByString(" ")

    var formatter = NSNumberFormatter()
    formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle

    if let price1 = formatter.numberFromString(myArr1[0]) as NSNumber! {
        if let price2 = formatter.numberFromString(myArr2[0]) as NSNumber!{
            return first < second
        }
    } 
    return false
}

for deal in deals{
    print("\(deal.deal)\n")
}

【问题讨论】:

  • 是的,我可以,但是在这一点上,如果比较错误,我如何得到数字并不重要。您认为将其更改为直接比较会解决问题吗?
  • 我认为您应该将其存储为 Double 并在显示时将其格式化为货币。
  • 我最终做了类似的事情。我的交易不仅包含一美元,还包含一些文本。所以我需要单独存储美元金额。不过谢谢你的建议!
  • 顺便说一句,不需要将字符串转换为字符串

标签: ios arrays sorting swift substring


【解决方案1】:

编辑:我知道你已经接受了一个答案,但是 FWIW,根据你自己的问题编辑,我在下面更新了我的答案,向你展示你的游乐场代码必须如何更改让我最初的建议发挥作用。

deals.sort{
    let myArr1 = $0.deal.componentsSeparatedByString(" ")
    let myArr2 = $1.deal.componentsSeparatedByString(" ")
    let formatter = NSNumberFormatter()
    formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle

    if let price1 = formatter.numberFromString(myArr1[0]) {
        if let price2 = formatter.numberFromString(myArr2[0]) {
            return price1.floatValue < price2.floatValue
        }
    }
    return false
}

另一个建议是,如果你有一个 Deal 类,你可以做得更简单,它有一个返回交易浮点值的特定属性,如下所示:

var dealValue: Float {
    get {
        let myArr = self.deal.componentsSeparatedByString(" ")
        let formatter = NSNumberFormatter()
        formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
        if let price = formatter.numberFromString(myArr[0]) {
            return price.floatValue
        } else {
            return 0
        }
    }
}

那么你之前的代码就变成了:

deals.sort { $0.dealValue < $1.dealValue }

【讨论】:

  • 我刚刚对您的代码进行了一些修改。 let 语句总是返回 null。我用我的代码编辑了原始帖子。
  • 我正在删除 $ 并仍在使用导致错误的 CurrencyStyle。傻我。但是,我不能返回 price1
  • 这个例子不适用..."$89" "$2.95" "$9.95" "$99.95" :/
  • 在您尝试从字符串中获取它们的值之后,您能否NSLog 获取price1price2 变量的值?在解析完数组后,还可以尝试 NSLog myArr1myArr2 数组的内容。请注意,您已经大大改变了最初的问题,所以我的回答目前感觉与您当前的问题有些脱节......
  • 我一直在使用 Playground 来查看输出。我将我的游乐场代码添加到原始代码中,以便您可以加载并尝试它。这几乎就像它不适用于两位数。
【解决方案2】:

问题的根源在于您是按字母顺序排序而不是按数字排序。从数值上看,4.25 排在 10.25 之前,因为 4.25 &lt; 10.25。按字母顺序,10.99 在 4.25 之前,因为 1 的字符代码小于 4 的字符代码。要解决此问题,您显然需要以某种方式获取与交易价格相对应的数字。

您可以编写一个方法,从记录中提取价格并将其作为数字返回,然后您可以正确比较。更好的是,将每笔交易存储为字典或其他结构,以便价格已经被分解为单独的值。

【讨论】:

  • 这就是我需要的解释。我使用了 Romain 的建议并添加了一个包含浮点数的“数量”属性,因此排序很容易比较。非常感谢你们!
【解决方案3】:

我认为您应该将其存储为 Double 并在显示时将其格式化为货币。

extension Double {
    var currency:String {
        let formatter = NSNumberFormatter()
        formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
        return formatter.stringFromNumber(self)!
    }
}
var deals: [(deal:Double, bar:String)] = []
deals.append(deal: 0.95 , bar: "bar")
deals.append(deal: 2.95 , bar: "bar")
deals.append(deal: 11.95, bar: "bar")
deals.append(deal: 3.95, bar: "bar")


deals.sort {$0.deal<$1.deal}

for deal in deals{
    print("\(deal.deal.currency)\n")
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-07
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    • 2017-01-22
    • 1970-01-01
    相关资源
    最近更新 更多