在Swift中为整数添加千位分隔符

77

我对Swift还比较新,但是却很难找到以千位分隔符的方式添加空格的方法。

我希望实现的功能是:将计算结果显示在文本框中,并以以下格式显示:

2 358 000

而不是像下面这样:

2358000

例如。

我不确定是否应该先对Int值进行格式化,然后再将其转换为String,或者在将Int值转换为String之后添加空格。非常感谢任何帮助。

7个回答

180

编辑/更新: 使用新的通用 formatted 方法(iOS15+/Xcode 13.0+):

当前区域设置

2358000.formatted()      // "2,358,000"

固定地区
2358000.formatted(.number.locale(.init(identifier: "fr_FR")))  // "2 358 000"
2358000.formatted(.number.locale(.init(identifier: "pt_BR")))  // "2.358.000"

原始帖子

您可以使用NSNumberFormatter来指定不同的分组分隔符,如下所示:

更新:Xcode 11.5 • Swift 5.2

extension Formatter {
    static let withSeparator: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        formatter.groupingSeparator = " "
        return formatter
    }()
}

extension Numeric {
    var formattedWithSeparator: String { Formatter.withSeparator.string(for: self) ?? "" }
}

2358000.formattedWithSeparator  // "2 358 000"
2358000.99.formattedWithSeparator  // "2 358 000.99"

let int = 2358000
let intFormatted = int.formattedWithSeparator  // "2 358 000"

let decimal: Decimal = 2358000
let decimalFormatted = decimal.formattedWithSeparator  // "2 358 000"

let decimalWithFractionalDigits: Decimal = 2358000.99
let decimalWithFractionalDigitsFormatted = decimalWithFractionalDigits.formattedWithSeparator // "2 358 000.99"

如果您需要以当前区域设置或固定区域设置显示货币值,请使用以下方法:
extension Formatter {
    static let number = NumberFormatter()
}
extension Locale {
    static let englishUS: Locale = .init(identifier: "en_US")
    static let frenchFR: Locale = .init(identifier: "fr_FR")
    static let portugueseBR: Locale = .init(identifier: "pt_BR")
    // ... and so on
}
extension Numeric {
    func formatted(with groupingSeparator: String? = nil, style: NumberFormatter.Style, locale: Locale = .current) -> String {
        Formatter.number.locale = locale
        Formatter.number.numberStyle = style
        if let groupingSeparator = groupingSeparator {
            Formatter.number.groupingSeparator = groupingSeparator
        }
        return Formatter.number.string(for: self) ?? ""
    }
    // Localized
    var currency:   String { formatted(style: .currency) }
    // Fixed locales
    var currencyUS: String { formatted(style: .currency, locale: .englishUS) }
    var currencyFR: String { formatted(style: .currency, locale: .frenchFR) }
    var currencyBR: String { formatted(style: .currency, locale: .portugueseBR) }
    // ... and so on
    var calculator: String { formatted(groupingSeparator: " ", style: .decimal) }
}

使用方法:

1234.99.currency    // "$1,234.99"

1234.99.currencyUS  // "$1,234.99"
1234.99.currencyFR  // "1 234,99 €"
1234.99.currencyBR  // "R$ 1.234,99"

1234.99.calculator  // "1 234.99"

注意:如果您想要一个与句号宽度相同的空格,可以使用"\u{2008}"

unicode spaces

formatter.groupingSeparator = "\u{2008}"

25
不要设置分隔符,让格式化程序根据语言环境选择一个。 - Sulthan
3
@Sulthan没有任何语言环境可以提供给他半角空格。 - Leo Dabus
能帮我把这个添加到文本框里吗?怎样做呢?当我们在文本框中输入数字时,数字应该改变(千位后添加空格)。 - Аба-Бакри Ибрагимов
@Аба-БакриИбрагимов https://dev59.com/R2Af5IYBdhLWcg3w9Wiu#34294660 - Leo Dabus

37
您想使用 NSNumberFormatter:
let fmt = NSNumberFormatter()
fmt.numberStyle = .DecimalStyle
fmt.stringFromNumber(2358000)  // with my locale, "2,358,000"
fmt.locale = NSLocale(localeIdentifier: "fr_FR")
fmt.stringFromNumber(2358000)  // "2 358 000"

我不知道法国(或任何国家)使用空格作为分隔符。我最喜欢的样式一直是每3位数字一个空格,整数部分和小数部分之间用句点分隔...我从一本旧的数学书中学到了这个样式,从未在其他地方看到过...这正是法国人所做的吗? - ArtOfWarfare
@ArtOfWarfare 许多编程语言将逗号用作小数分隔符,但在千位分隔符上使用空格或句点有所不同(例如,法语和德语使用空格,西班牙语和意大利语使用句点)。我认为英语在小数点使用句点方面处于少数(可能只有一个)。 - Airspeed Velocity
@AirspeedVelocity 实际上,在德语中,千位分隔符使用句号(.),小数点分隔符使用逗号(,)。因此,英语中的1,234.56在德语中为1.234,56。 - Manuel
意大利:千位使用句点(1.000),小数使用逗号。这凸显了让格式化程序自行格式化格式和格式化程序的必要性。 - user5306470

25

使用Swift 5,当您需要格式化数字的显示时,NumberFormatter是正确的工具。


NumberFormatter有一个名为numberStyle的属性。可以将numberStyle设置为NumberFormatter.Style.decimal,以将格式化程序的样式设置为十进制。

因此,在最简单的情况下,当您想要使用十进制样式格式化数字时,可以使用以下Playground代码:

import Foundation

let formatter = NumberFormatter()
formatter.numberStyle = NumberFormatter.Style.decimal

let amount = 2358000
let formattedString = formatter.string(for: amount)
print(String(describing: formattedString))

根据用户当前的语言环境,此代码将在en_US环境下显示Optional("2,358,000"),在fr_FR环境下显示Optional("2 358 000")
请注意,以下代码片段使用 NumberFormatterlocale 属性设置为 Locale.current,与之前的 Playground 代码等效。
import Foundation

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.locale = Locale.current

let amount = 2358000
let formattedString = formatter.string(for: amount)
print(String(describing: formattedString))

下面的游乐场代码使用NumberFormattergroupingSeparator属性设置为Locale.current.groupingSeparator,与前者等效:
import Foundation

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.groupingSeparator = Locale.current.groupingSeparator

let amount = 2358000
let formattedString = formatter.string(for: amount)
print(String(describing: formattedString))

否则,如果您想使用特定的语言环境格式样式设置数字格式,请使用以下 Playground 代码:
import Foundation

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.locale = Locale(identifier: "fr_FR")

let amount = 2358000
let formattedString = formatter.string(for: amount)
print(String(describing: formattedString))
// prints: Optional("2 358 000")

然而,如果你真正想要强制使用特定的分组分隔符,可以使用下面的Playground代码:

import Foundation

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.groupingSeparator = " "

let amount = 2358000
let formattedString = formatter.string(for: amount)
print(String(describing: formattedString))
// prints: Optional("2 358 000")

11
Leo Dabus的回答翻译成Swift 3:

在任何一个.swift文件中,在类的外面:

struct Number {
    static let withSeparator: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.groupingSeparator = " " // or possibly "." / ","
        formatter.numberStyle = .decimal
        return formatter
    }()
}
extension Integer {
    var stringWithSepator: String {
        return Number.withSeparator.string(from: NSNumber(value: hashValue)) ?? ""
    }
}

用法:

let myInteger = 2358000
let myString = myInteger.stringWithSeparator  // "2 358 000"

我使用了self而不是hashValue。 - Ahmadreza

1

代码:

//5000000
let formatter = NumberFormatter()
formatter.groupingSeparator = " "
formatter.locale = Locale(identifier: "en_US")
formatter.numberStyle = .decimal. 

输出:

5 000 000


0

我正在寻找像 $100,000.00 这样的货币格式, 通过自定义 Leo Dabus 的实现,我成功地完成了它

extension Formatter {
    static let withSeparator: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.currencyGroupingSeparator = ","
        formatter.locale = Locale(identifier: "en_US") //for USA's currency patter
        return formatter
    }()
}

extension Numeric {
    var formattedWithSeparator: String {
        return Formatter.withSeparator.string(for: self) ?? ""
    }
}

1
在设置其他属性之前,应该先设置区域设置。另外,如果将区域设置固定为"en_US",就不需要设置货币分组分隔符。 - Leo Dabus

-4

试试这个

func addPoints(inputNumber: NSMutableString){
    var count: Int = inputNumber.length
    while count >= 4 {
        count = count - 3
        inputNumber.insert(" ", at: count) // you also can use "," 
    }
    print(inputNumber)
}

调用:

addPoints(inputNumber: "123456")

结果如下:

123 456(或者 123,456)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接