Swift - 对美元值数组进行排序

Swift - Sorting array of dollar values

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

“$2.25 饮料 A”

“5 美元饮料 B”

“10 美元饮料 C”

等等

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

    deals.sort {
        var first = [=11=].deal as String
        var second = .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 美元之类的东西,它不会正确排序。

这是我正在使用的 playground 测试代码

import UIKit


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

deals.append(deal: "[=12=].95" as String, bar: "bar" as String)
deals.append(deal: ".95" as String, bar: "bar" as String)
deals.append(deal: ".95" as String, bar: "bar" as String)
deals.append(deal: ".95" as String, bar: "bar" as String)


deals.sort {
    var first = [=12=].deal as String
    var second = .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")
}

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

deals.sort{
    let myArr1 = [=10=].deal.componentsSeparatedByString(" ")
    let myArr2 = .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 class,并且带有返回交易浮点值的特定 属性,您可以做得更简单,如下所示:

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 { [=12=].dealValue < .dealValue }

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

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

我认为您应该将其存储为 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 {[=10=].deal<.deal}

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