Format Int64 with thousand separators
You mean when you call numberFormatter.stringFromNumber(12345678)
after the above code, like this?
let i64: Int64 = 1234567890
numberFormatter.stringFromNumber(i64)
Doesn’t look like Swift will cast from an Int64
to an NSNumber
:
let i = 1234567890
let n = i as NSNumber // OK
numberFormatter.stringFromNumber(i) // Also OK
// Compiler error: 'Int64' is not convertible to 'NSNumber'
let n64 = i64 as NSNumber
// so the implicit conversion will also fail:
numberFormatter.stringFromNumber(i64)
This is a bit confounding, since Swift Int
s are themselves usually the same size as Int64
s.
You can work around it by constructing an NSNumber
by hand:
let n64 = NSNumber(longLong: i64)
BTW beware that var
trick: it’s nice that it encapsulates all the relevant code for creating numberFormatter
, but that code will run afresh every time you use it. As an alternative you could do this:
let numberFormatter: NSNumberFormatter = {
let formattedNumber = NSNumberFormatter()
formattedNumber.numberStyle = .DecimalStyle
formattedNumber.maximumFractionDigits = 0
return formattedNumber
}()
If it’s a property in a struct/class, you could also make it a lazy var
which has the added benefit of only being running if the variable is used, like your var
, but only once.
struct Thing {
lazy var numberFormatter: NSNumberFormatter = {
println("blah")
let formattedNumber = NSNumberFormatter()
formattedNumber.numberStyle = .DecimalStyle
formattedNumber.maximumFractionDigits = 0
return formattedNumber
}()
}
extension Formatter {
static let decimalNumber: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
return formatter
}()
}
extension Numeric {
var formatted: String { Formatter.decimalNumber.string(for: self) ?? "" }
}
let x: Int64 = 1000000
x.formatted // "1,000,000"