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:
Related Topics
Raw Value of Enumeration, Default Value of a Class/Structure, What's the Different
How to Handle Two Possible Date Formats
Why Can't I Use 'Type' as the Name of an Enum Embedded in a Struct
Unexpectedly Found Nil While Unwrapping an Optional Value While Reading from Ds with Fromcstring
Is There a Neat Way to Represent a Fraction as an Attributed String
How to Pass Arguments into a Function with Completion Swift
How to Sort an Array of Posts by Their Elements
Where to Place App Delegate Code in App.Swift File
Presenting a Uiviewcontroller from Skscene Shows Black Screen
With Data (Not Nsdata), in Fact How Actually Do You Make a Utf8 Version of a Jpeg
Swift: Download Image from Internet and Cache Them Doesn't Work Properly. Need Suggestions
Swiftui How to Invoke the Function and Change View from Other Page
What Is the Shortest Way to Run Same Code N Times in Swift
How to Change Uitextfield Keyboard Type to Email in Swift
Differencebetween Sequencetype and Collectiontype in Swift