使用NSNumberFormatter在十进制后生成带尾随零的数字

在Swift中,你将如何创build一个NSNumberFormatter来保存十进制(12.000)后面的零,同时生成一个适合当前语言环境的数字?

我目前的代码和示例输出:

 let formatter = NSNumberFormatter() formatter.numberStyle = .DecimalStyle formatter.locale = NSLocale.currentLocale() formatter.maximumFractionDigits = 10 var doubleNumString = "12.0" println(formatter.numberFromString(doubleNumString)) //in English it prints 12, want it to print 12.0 var doubleNumString = "12.000" println(formatter.numberFromString(doubleNumString)) //prints 12, want it to print 12.000 var doubleNumString = "12.125" println(formatter.numberFromString(doubleNumString)) //prints 12.125 as expected var doubleNumString = "1234" println(formatter.numberFromString(doubleNumString)) //prints 1,234 as expected 

我已经编码它,如果string以十进制( "12." )结尾,那么它不会使用这个格式化程序来生成数字,而只是显示数字,然后小数点(但我需要改善因为有些语言从右向左读)。

一种解决方法是检查string是否包含句点,如果是,检查后面的所有数字是否为0,如果是,则不要通过数字格式化程序运行,而是通过格式化程序只运行int值附加/前面加上小数,后面跟着适当数量的0。

有更好的/更清洁的解决scheme吗?

正如Martin R所提到的,您可以将minimumFractionDigitsminimumFractionDigits设置为相同的数字,这将强制显示许多小数位。 要知道有多less显示你需要采取一个小数点后的子串到结束并计算其元素。 要知道是否所有的小数位是0,我创build了一个帮助器的方法,将该子string转换为一个数字,如果它等于0,那么你知道他们都是0的。

不幸的是,你需要使用基于原始string数的几个不同的NSNumberFormatter将string转换为本地化的数字。 所以如果它包含一个十进制数,并且它是0之后的所有数据,那么你需要创build一个不同的格式化程序,将该string转换为一个数字,然后将该数字转换为一个string,以便根据用户的语言环境进行显示。 否则,您可以使用您的原始数字格式化程序。

这个function照顾你的要求。 从语言环境(例如en_US)传递相同的

 + (NSString*) stringForString:(NSString*) string forLocale:(NSString*) toLocaleCode fromLocal:(NSString*) fromLocaleCode { NSLocale *fromLocale = [[NSLocale alloc] initWithLocaleIdentifier:fromLocaleCode]; NSNumberFormatter *sourceFormatter = [[NSNumberFormatter alloc] init]; [sourceFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; [sourceFormatter setUsesGroupingSeparator:NO]; [sourceFormatter setLocale:fromLocale]; NSNumber *localizedNumber = [sourceFormatter numberFromString:string]; if (!localizedNumber) { return string; } NSLocale *toLocale = [[NSLocale alloc] initWithLocaleIdentifier:toLocaleCode]; NSNumberFormatter *destinationFormatter = [[NSNumberFormatter alloc] init]; [destinationFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; [destinationFormatter setUsesGroupingSeparator:NO]; [destinationFormatter setLocale:toLocale]; NSString *localizedString = [destinationFormatter stringFromNumber:localizedNumber]; //add the zeros which were dropped because of the sourceDecimalString number conversion eg 0.20 is converted to 0.2 if (localizedString.length < string.length) { NSRange rangeOfDecimal = [string rangeOfString:sourceFormatter.decimalSeparator]; if (rangeOfDecimal.location != NSNotFound) { NSString* sourceDecimalString = [string substringFromIndex:rangeOfDecimal.location]; rangeOfDecimal = [localizedString rangeOfString:destinationFormatter.decimalSeparator]; if (rangeOfDecimal.location != NSNotFound) { NSString* destinationDecimalString = [localizedString substringFromIndex:rangeOfDecimal.location]; if (destinationDecimalString.length < sourceDecimalString.length) { int difference = sourceDecimalString.length - destinationDecimalString.length; int toalDecimalDigits = (destinationDecimalString.length - 1) + difference; //-1 to remove '.' destinationFormatter.minimumFractionDigits = toalDecimalDigits; destinationFormatter.maximumFractionDigits = toalDecimalDigits; localizedString = [destinationFormatter stringFromNumber:localizedNumber]; } } else{//this indicates no decimal separator in the return string int toalDecimalDigits = (sourceDecimalString.length - 1); //-1 to remove '.' destinationFormatter.minimumFractionDigits = toalDecimalDigits; destinationFormatter.maximumFractionDigits = toalDecimalDigits; localizedString = [destinationFormatter stringFromNumber:localizedNumber]; } } } return localizedString; }