116

How would I add commas to a number that I'm retrieving from a JSON in swift.

Example
31908551587 to
31,908,551,587

I'm so confused and I have no idea what to do.

burnsi
  • 6,194
  • 13
  • 17
  • 27
Omar Qureshi
  • 1,299
  • 2
  • 8
  • 8

8 Answers8

211

You can do it with 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)
Ben
  • 3,346
  • 6
  • 32
  • 51
Özgür Ersil
  • 6,909
  • 3
  • 19
  • 29
68

Expanding on Özgür Ersil's answer, you can isolate the functionality with an extesion to Int:

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

To then use on your code as:

largeNumber.withCommas()
Sunil Targe
  • 7,251
  • 5
  • 49
  • 80
Juan Fran Jimenez
  • 1,629
  • 15
  • 19
16

Also expanding on Juan Fran Jimenez's answer, I would recommend putting the formatter into a singleton, since instantiating a formatter is usually a relatively expensive operation. (It could affect the performance if you're formatting on-the-go as the user writes.)

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
  • 1,401
  • 11
  • 20
9

A simple drop in extension that will provide a variable via an extension of Int.

As noted in Julien's answer, this makes use of a static formatter for performance reasons.

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)) ?? ""
    }
}

To use it:

let number = 31908551587
print(number.delimiter) // 31,908,551,587
CodeBender
  • 35,668
  • 12
  • 125
  • 132
  • 2
    ??? Your code is practically identical to Julien's answer. The only thing different is he has `internal var` and you just have `var`. What does your answer add to the conversation? Also, I would say your variable `delimiter` is misleading. Julien's `commaRepresentation` is much more useful. – Zonker.in.Geneva May 21 '20 at 07:46
5

This is an additional way of setting comma position. Let's say I want the number 10000000 to be printed as "1,00,00,000"

let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .decimal
numberFormatter.groupingSize = 3
numberFormatter.secondaryGroupingSize = 2
numberFormatter.string(from: 10000000)
Rikesh Subedi
  • 1,755
  • 22
  • 21
1

I have created a class for amount textfield. Simply set it to your textfield class. Ex- Enter 1234567. It will convert it to 1,234,567 Also work for decimal entry, will take two digits after 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
  • 111
  • 1
  • 9
1

Swift 4

let largeNumber = 31908551587
let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .decimal
let formattedNumber = numberFormatter.string(from: NSNumber(value:largeNumber))
Ben
  • 3,346
  • 6
  • 32
  • 51
0

Swift 5

If you want to use it for label:

private func formatNumberToThousand(number: Int) -> String {
    let numberFormatter = NumberFormatter()
    numberFormatter.numberStyle = .decimal
    numberFormatter.groupingSeparator = "."
    let formattedNumber = numberFormatter.string(from: NSNumber(value: number))
    return formattedNumber ?? ""
}

to use it:

let thousand = 193843
yourLabel.text = formatNumberToThousand(number: thousand)
//Output: 193.843