Number of Occurrences of a Character in NSString

You can do this in one line. For example, this counts the number of spaces:

NSUInteger numberOfOccurrences = [[yourString componentsSeparatedByString:@" "] count] - 1;

Try this category on NSString:

@implementation NSString (OccurrenceCount)

- (NSUInteger)occurrenceCountOfCharacter:(UniChar)character
{
    CFStringRef selfAsCFStr = (__bridge CFStringRef)self;

    CFStringInlineBuffer inlineBuffer;
    CFIndex length = CFStringGetLength(selfAsCFStr);
    CFStringInitInlineBuffer(selfAsCFStr, &inlineBuffer, CFRangeMake(0, length));

    NSUInteger counter = 0;

    for (CFIndex i = 0; i < length; i++) {
        UniChar c = CFStringGetCharacterFromInlineBuffer(&inlineBuffer, i);
        if (c == character) counter += 1;
    }

    return counter;
}

@end

This one is approximately 5 times faster than the componentsSeparatedByString: approach.


replaceOccurrencesOfString:withString:options:range: will return the number of characters replaced in a NSMutableString.

[string replaceOccurrencesOfString:@"A" 
                        withString:@"B" 
                           options:NSLiteralSearch 
                             range:NSMakeRange(0, [receiver length])];

Whenever you are looking for things in a NSString, try using NSScanner first.

NSString *yourString = @"ABCCDEDRFFED"; // For example
NSScanner *scanner = [NSScanner scannerWithString:yourString];

NSCharacterSet *charactersToCount = [NSCharacterSet characterSetWithCharactersInString:@"C"]; // For example
NSString *charactersFromString;

if (!([scanner scanCharactersFromSet:charactersToCount 
                          intoString:&charactersFromString])) {
    // No characters found
    NSLog(@"No characters found");
}

// should return 2 for this
NSInteger characterCount = [charactersFromString length];

Nowadays the first thing that come to my mind for something like that: NSCountedSet

NSString *string = @"AAATTC";

NSMutableArray *array = [NSMutableArray array];

[string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
    [array addObject:substring];
}] ;
NSCountedSet * set = [[NSCountedSet alloc] initWithArray:array];

for (NSString *nucleobase in @[@"C", @"G", @"A", @"T"]){
    NSUInteger count = [set countForObject:nucleobase];
    NSLog(@"%@: %lu", nucleobase, (unsigned long)count);
}

logs:

C: 1
G: 0
A: 3
T: 2