Swift How to Format a Large Number with Thousands Separators

Swift how to format a large number with thousands separators?

Swift Xcode 6.3, SOLVED (I decided to leave the $ in the code). If you don't want a $ in the output, change .CurrencyStyle to .DecimalStyle

var fv = 3534234.55 
var formatter = NSNumberFormatter()
formatter.numberStyle = .CurrencyStyle
formatter.maximumFractionDigits = 0;
resultFV.text = formatter.stringFromNumber(fv) // result: $3,534,235 –

Adding Thousand Separator to Int in Swift

You can use NSNumberFormatter to specify a different grouping separator as follow:

update: 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"

If you need to display your value as currency with current locale or with a fixed locale:

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

Usage:

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"

Note: If you would like to have a space with the same width of a period you can use "\u{2008}"

unicode spaces

formatter.groupingSeparator = "\u{2008}"

Format a number to string with thousand separators and always has 2 digits after decimal point in swift

See NSNumberFormatter.minimumFractionDigits.

let formatter = NSNumberFormatter()
formatter.numberStyle = .DecimalStyle
formatter.minimumFractionDigits = 2
let s2 = formatter.stringFromNumber(n) //5,432.10

Adding Thousand Separator Automatically (Swift)

It is better to accumulate your value in a separate string that doesn't have the formatting applied rather than using the text field as your data model. You can then format the decimal and display it in the label as required using a NumberFormatter:

let formatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
return formatter
}()

var currentInput: String = "0" {
didSet {
self.displayResultLabel?.text = self.currentDisplay
}

var currentValue: Double {
return Double(self.currentInput) ?? 0
}

var currentDisplay: String {
return formatter.string(from: NSNumber(value:self.currentValue)) ?? "0"
}

func addDigit(_ digit: Int) {
if currentInput.count < 14 {
let newValue = self.currentValue * 10 + Double(digit)
self.currentInput = "\(newValue)"
}
}

@IBAction func numberPressed(_ sender: UIButton) {
guard let digit = Int(sender.currentTitle!) else {
return
}

self.addDigit(digit)
}

Swift NumberFormatter just for thousand

You ask:

why there is no separator in 1000?

This pattern, of omitting the grouping separator when there are only four digits, is not uncommon for languages that use a space as the separator.

As Exceptions to digit grouping says:

The International Bureau of Weights and Measures states that “when there are only four digits before or after the decimal marker, it is customary not to use a space to isolate a single digit”.

You will see this pattern in several locales that use space as the grouping separator.


This formatting is based upon the device’s settings (as represented by your current Locale). You can test to see what it looks like for other users in other locales by just temporarily changing your device settings.

I would be wary about manually adjust locale property of the formatter for desired output: Sure, one may do that for diagnostic purposes, but generally you do not want to change the locale of the formatter (with the obvious exception where you need some invariant format, for example, storing results in persistent storage or sending to a server).

Always use the device’s current locale so you honor the number formatting wishes of the end user.

iOS convert large numbers to smaller format

Here are two methods I have come up with that work together to produce the desired effect. This will also automatically round up. This will also specify how many numbers total will be visible by passing the int dec.

Also, in the float to string method, you can change the @"%.1f" to @"%.2f", @"%.3f", etc to tell it how many visible decimals to show after the decimal point.

For Example:

52935 ---> 53K
52724 ---> 53.7K

-(NSString *)abbreviateNumber:(int)num withDecimal:(int)dec {

NSString *abbrevNum;
float number = (float)num;

NSArray *abbrev = @[@"K", @"M", @"B"];

for (int i = abbrev.count - 1; i >= 0; i--) {

// Convert array index to "1000", "1000000", etc
int size = pow(10,(i+1)*3);

if(size <= number) {
// Here, we multiply by decPlaces, round, and then divide by decPlaces.
// This gives us nice rounding to a particular decimal place.
number = round(number*dec/size)/dec;

NSString *numberString = [self floatToString:number];

// Add the letter for the abbreviation
abbrevNum = [NSString stringWithFormat:@"%@%@", numberString, [abbrev objectAtIndex:i]];

NSLog(@"%@", abbrevNum);

}

}

return abbrevNum;
}

- (NSString *) floatToString:(float) val {

NSString *ret = [NSString stringWithFormat:@"%.1f", val];
unichar c = [ret characterAtIndex:[ret length] - 1];

while (c == 48 || c == 46) { // 0 or .
ret = [ret substringToIndex:[ret length] - 1];
c = [ret characterAtIndex:[ret length] - 1];
}

return ret;
}

Hope this helps anyone else out who needs it!

Swift. How to set custom number format? With space thouthand separator and two digits after point

let d1: Double = 20000000.0
let d2: Double = 1.2345

let formatter = NumberFormatter()
formatter.groupingSeparator = " "
formatter.numberStyle = .decimal
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
formatter.decimalSeparator = "." // Default separator is dependent to the current local.

print(formatter.string(for: d1)) // 20 000 000.00
print(formatter.string(for: d2)) // 1.23

Swift: Thousand separator in localised strings using Localizable.stringsdict

How about this:

let s = String(format: format, locale: Locale.current, arguments: [item1000])
print(s) //1,000 new Continents

(The locale does change number formatting.)

Given the dictionary:

<dict>
<key>WNC_NewContinents</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@variable@</string>
<key>variable</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>zero</key>
<string>new Continents</string>
<key>one</key>
<string>%d new Continent</string>
<key>other</key>
<string>%d new Continents</string>
</dict>
</dict>

Here is what it gives in a playground:

1000



Related Topics



Leave a reply



Submit