2014-10-28 111 views
0

在Swift中,如何創建一個NSNumberFormatter來保留小數點後的零(12.000),同時還生成適合當前語言環境的數字?使用NSNumberFormatter在十進制後生成尾隨零的數字

我當前的代碼和示例輸出:

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 

我已經編碼它這樣如果字符串中十進制("12.")結束,那麼它不會使用此格式生成數,會使而只是顯示數字,然後顯示小數(但我需要改進,因爲一些語言從右向左讀)。

一個解決方案是檢查字符串是否包含句點,如果是,檢查後面的所有數字是否爲0,如果是,則不要通過數字格式化程序運行它,而只運行int值通過格式化程序,然後附加/預先加上小數,然後加上適當數量的0。

是否有更好的/更清潔的解決方案?

+1

A *編號*不具有尾隨零,只有其* *字符串表示。將「12.0」和「12.000」轉換爲*號*給出完全相同的結果,並且無法將它們區分爲數字。 - 爲什麼你不能只使用字符串本身? – 2014-10-28 06:13:45

+0

@Martin,因爲字符串始終爲英文格式,並且輸出數字需要尊重當前語言環境,但如果它們存在於字符串中,則還會保留任何尾隨零。 – Joey 2014-10-28 06:22:25

+1

然後你可以轉換string-> number-> string,但是你必須計算尾隨零的數量並將其設置爲第二次轉換的minimum + maximumFractionDigits。也許這有幫助,現在沒有時間去嘗試並寫出答案。 – 2014-10-28 06:31:58

回答

1

正如Martin R所述,您可以將minimumFractionDigitsmaximumFractionDigits設置爲相同的數字,這將強制顯示許多小數位。要知道需要顯示多少個字符,需要在小數點後面接一個子字符串並計算其元素。要知道是否所有的小數位都是0,我創建了一個幫助器方法,將該子串轉換爲數字,如果它等於0,則知道它們全爲0。

不幸的是,您需要根據原始字符串編號,使用不同的NSNumberFormatter s將字符串轉換爲本地化號碼。因此,如果它包含一個小數,並且其後的所有內容都是0,那麼您需要創建一個不同的格式化程序,將該字符串轉換爲數字,然後將該數字轉換爲字符串以便根據用戶的區域設置進行顯示。否則,您可以使用您的原始數字格式器。

-1

此功能照顧您的要求。通過同爲&從區域設置(例如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 e.g. 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; 
}