staticnz
staticnz

Reputation: 491

Formatting a string containing a number with comma separation

I have a number stored in an NSMutableString instance which I want to auto format with comma delimiters and then display the result in a UITextField.

I've tried using NSNumberFormatter to format as currency, but I don't want it to show decimals if the original NSMutableString doesn't contain a decimal place.

For example:

The maximum decimals that the NSMutableString will contain is 2.

Any help is greatly appreciated.

Thanks!

Upvotes: 4

Views: 3082

Answers (4)

Dinesh
Dinesh

Reputation: 41

Just call this method to be simple:

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

Upvotes: 1

lnafziger
lnafziger

Reputation: 25740

Keep in mind that you should really be localizing this if you are interacting with users on this, however here is one way to do it:

- (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

Upvotes: 7

rdelmar
rdelmar

Reputation: 104092

I think this should do it -- I added an if statement to check if there is a decimal point in the typed in value. "Output" in this example is a property that I have bound to the value of a text field to show the result.

-(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]];
    }
}

Upvotes: 1

Amy Worrall
Amy Worrall

Reputation: 16337

You're looking for the -setMinimumFractionDigits: method on NSNumberFormatter. Set that to 0 and it'll only display the decimal point if there's anything to put after it.

Upvotes: 0

Related Questions