como adicionar vírgulas a um número rapidamente?

87

Como eu adicionaria vírgulas a um número que estou recuperando de um JSON no swift.

Example
31908551587 to
31,908,551,587

Estou tão confuso e não tenho ideia do que fazer.

Omar Qureshi
fonte

Respostas:

171

Você pode fazer isso com NSNumberFormatter

Swift 4

let largeNumber = 31908551587
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .decimal
let formattedNumber = numberFormatter.string(from: NSNumber(value:largeNumber))

Swift 3

 let largeNumber = 31908551587
 let numberFormatter = NumberFormatter()
 numberFormatter.numberStyle = NumberFormatter.Style.decimal
 let formattedNumber = numberFormatter.string(from: NSNumber(value:largeNumber))

Swift 2

 let largeNumber = 31908551587
 let numberFormatter = NSNumberFormatter()
 numberFormatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
 let formattedNumber = numberFormatter.stringFromNumber(largeNumber)
Özgür Ersil
fonte
existe alguma maneira de fazer assim '31, 90,85,51,587 'usando NumberFormatter?
Sanket_B
@SanketBhavsar, acho que não, verifique
Özgür Ersil
2
@ ÖzgürErsil Eu fiz isso com moeda (estilo)
Sanket_B
como fazer reverso
Yestay Muratov
Existe alguma maneira de converter 1000000000000000 em 1.000.000.000.000.000 ?? Porque isto funciona para sete 0 após o número ...
Cemal BAYRI
48

Expandindo a resposta de Özgür Ersil, você pode isolar a funcionalidade com uma extensão para Int:

extension Int {
    func withCommas() -> String {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal
        return numberFormatter.string(from: NSNumber(value:self))!
    }
}

Para usar em seu código como:

largeNumber.withCommas()
Juan Fran Jimenez
fonte
12

Também expandindo a resposta de Juan Fran Jimenez, eu recomendaria colocar o formatador em um singleton, uma vez que instanciar um formatador geralmente é uma operação relativamente cara. (Isso pode afetar o desempenho se você formatar em trânsito, conforme o usuário escreve.)

extension Int {

    private static var commaFormatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        return formatter
    }()

    internal var commaRepresentation: String {
        return Int.commaFormatter.string(from: NSNumber(value: self)) ?? ""
    }
}
Julien Perrenoud
fonte
10

Uma simples queda na extensão que fornecerá uma variável por meio de uma extensão de Int.

Conforme observado na resposta de Julien, ele usa um formatador estático por motivos de desempenho.

extension Int {
    private static var numberFormatter: NumberFormatter = {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal

        return numberFormatter
    }()

    var delimiter: String {
        return Int.numberFormatter.string(from: NSNumber(value: self)) ?? ""
    }
}

Para usá-lo:

let number = 31908551587
print(number.delimiter) // 31,908,551,587
CodeBender
fonte
1
??? Seu código é praticamente idêntico à resposta de Julien. A única coisa diferente é que ele tem internal vare você apenas tem var. O que sua resposta adiciona à conversa? Além disso, eu diria que sua variável delimiteré enganosa. O de Julien commaRepresentationé muito mais útil.
Zonker.in.Geneva
2

Esta é uma forma adicional de definir a posição da vírgula. Digamos que eu queira que o número 10000000 seja impresso como "1,00,00,000"

let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .decimal
numberFormatter.groupingSize = 3
numberFormatter.secondaryGroupingSize = 2
numberFormatter.string(from: 10000000)
Rikesh Subedi
fonte
1

Swift 4

let largeNumber = 31908551587
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .decimal
let formattedNumber = numberFormatter.string(from: NSNumber(value:largeNumber))
Ben
fonte
0

Eu criei uma classe para o campo de texto amount. Basta configurá-lo para sua classe de campo de texto. Ex- Digite 1234567. Ele irá convertê-lo para 1.234.567. Também funciona para entrada decimal, terá dois dígitos após o decimal.

class AmountField: UITextField {

private var isFirstDecimal : Bool = true
override func willMove(toSuperview newSuperview: UIView?) {

    addTarget(self, action: #selector(editingChanged), for: .editingChanged)
    keyboardType = .decimalPad
    textAlignment = .left
    placeholder = "0.0"
    editingChanged()
}
override func deleteBackward() {
    var currentText = self.text ?? ""
    currentText = String(currentText.dropLast())
    self.text = currentText
    editingChanged(self)
}
@objc func editingChanged(_ textField: UITextField? = nil) {
    var doubleStr = textField?.text ?? "00"


    let decimalCount = doubleStr.components(separatedBy: ".")
    if decimalCount.count > 2 {
        var currentText = self.text ?? ""
        currentText = String(currentText.dropLast())
        self.text = currentText
        return
    }

    if doubleStr.contains(".") && isFirstDecimal == true {
        self.text = doubleStr
        isFirstDecimal = false
        return
    }
    else if !(doubleStr.contains(".")) {
        isFirstDecimal = true
    }

    let doubleStrTemp = doubleStr.replacingOccurrences(of: ",", with: "")

    if doubleStrTemp != "" {
        if let n = Decimal(string: doubleStrTemp )?.significantFractionalDecimalDigits {
            if n > 2 {
                var currentText = self.text ?? ""
                currentText = String(currentText.dropLast())
                self.text = currentText
                return
            }
        }
    }
    doubleStr = doubleStr.replacingOccurrences(of: ",", with: "")

    let doube = Double(doubleStr)
    let numberFormatter = NumberFormatter()
    numberFormatter.numberStyle = NumberFormatter.Style.decimal
    if doube != nil {
        let formattedNumber = numberFormatter.string(from: NSNumber(value:doube!))
        self.text = formattedNumber
    }
}}

extension Decimal {
var significantFractionalDecimalDigits: Int {
    return max(-exponent, 0)
}}
Vijay Patidar
fonte
Não, estou usando NSNumberFormatter. Para decimal e outras validações, coloquei condições separadas.
Vijay Patidar,