格式化包含逗号分隔的数字的字符串

时间:2012-03-24 23:45:19

标签: iphone objective-c ios nsnumberformatter

我有一个存储在NSMutableString实例中的数字,我想用逗号分隔符自动格式化,然后在UITextField中显示结果。

我尝试使用NSNumberFormatter格式化为货币,但如果原始NSMutableString不包含小数位,我不希望它显示小数。

例如:

  • 如果NSMutableString包含“1234567”,则格式为“1,234,567”。
  • 如果NSMutableString包含“1234567.1”,则格式为“1,234,567.1”
  • 如果NSMutableString包含“1234567.12”,则格式为“1,234,567.12”

NSMutableString将包含的最大小数为2。

非常感谢任何帮助。

谢谢!

4 个答案:

答案 0 :(得分:6)

请记住,如果您正在与用户进行交互,那么您应该真正进行本地化,但这是一种方法:

- (NSString *)formatString:(NSString *)string {
    // Strip out the commas that may already be here:
    NSString *newString = [string stringByReplacingOccurrencesOfString:@"," withString:@""];
    if ([newString length] == 0) {
        return nil;
    }

    // Check for illegal characters
    NSCharacterSet *disallowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet];
    NSRange charRange = [newString rangeOfCharacterFromSet:disallowedCharacters];
    if ( charRange.location != NSNotFound) {
        return nil;
    }

    // Split the string into the integer and decimal portions
    NSArray *numberArray = [newString componentsSeparatedByString:@"."];
    if ([numberArray count] > 2) {
        // There is more than one decimal point
        return nil;
    }

    // Get the integer
    NSString *integer           = [numberArray objectAtIndex:0];
    NSUInteger integerDigits    = [integer length];
    if (integerDigits == 0) {
        return nil;
    }

    // Format the integer.
    // You can do this by first converting to a number and then back to a string,
    // but I would rather keep it as a string instead of doing the double conversion.
    // If performance is critical, I would convert this to a C string to do the formatting.
    NSMutableString *formattedString = [[NSMutableString alloc] init];
    if (integerDigits < 4) {
        [formattedString appendString:integer];
    } else {
        // integer is 4 or more digits
        NSUInteger startingDigits = integerDigits % 3;
        if (startingDigits == 0) {
            startingDigits = 3;
        }
        [formattedString setString:[integer substringToIndex:startingDigits]];
        for (NSUInteger index = startingDigits; index < integerDigits; index = index + 3) {
            [formattedString appendFormat:@",%@", [integer substringWithRange:NSMakeRange(index, 3)]];
        }
    }

    // Add the decimal portion if there
    if ([numberArray count] == 2) {
        [formattedString appendString:@"."];
        NSString *decimal = [numberArray objectAtIndex:1];
        if ([decimal length] > 0) {
            [formattedString appendString:decimal];
        }
    }

    return formattedString;
}

// Test cases:
NSLog(@"%@", [self formatString:@"123456"]);
NSLog(@"%@", [self formatString:@"1234567."]);
NSLog(@"%@", [self formatString:@"12345678.1"]);
NSLog(@"%@", [self formatString:@"123456789.12"]);

// Output:
123,456
1,234,567.
12,345,678.1
123,456,789.12

答案 1 :(得分:1)

只需将此方法称为简单:

public static String GetCommaSeparatedCount(this Int32 Count)
    {
        // Check for The less-than character (<) is converted to &lt;
        String result = String.Format("{0:#,##0}", Count);

        return result;
    }

答案 2 :(得分:0)

您正在寻找NSNumberFormatter上的-setMinimumFractionDigits:方法。将其设置为0,如果有任何东西放在它后面,它只会显示小数点。

答案 3 :(得分:0)

我认为应该这样做 - 我添加了一个if语句来检查输入值中是否有小数点。此示例中的“输出”是一个属性,我已将其绑定到文本字段的值以显示结果。

-(IBAction)doConversion:(id)sender{
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc]init];
    [formatter setMaximumFractionDigits:2];
    [formatter setUsesGroupingSeparator:YES];
    [formatter setNumberStyle:NSNumberFormatterDecimalStyle];

    double entryFieldFloat = [entryField doubleValue]; 
    if ([entryField.stringValue rangeOfString:@"."].length == 1) {
        formatter.alwaysShowsDecimalSeparator = YES;
        self.output =[formatter stringFromNumber:[NSNumber numberWithDouble:entryFieldFloat]];
    }else{
        formatter.alwaysShowsDecimalSeparator = NO;
        self.output =[formatter stringFromNumber:[NSNumber numberWithDouble:entryFieldFloat]];
    }
}