views:

98

answers:

5

I am a bit new to Objective C and was wondering if there is a better way to count words in a string.

ie:

NSString *str = @"this is a string";

// return should be 4 words ..

The way I now how to do it is by breaking the string into an array of words space (' ') character and count the array.

Any advise will be appreciated! Thanks!! :)

EDIT: For those of you who came here looking for answer; I found a similar post with an excellent reply.

http://stackoverflow.com/questions/2266434/how-to-count-words-within-a-text-string

+2  A: 

Are you sure you have a bottleneck in that part of code? If not (which is quite probable), then splitting on spaces seems perfectly acceptable to me. You could create a C string and count the spaces instead, but a lot of times such an “optimized” version is actually slower than the original one. That is, assuming that your current code looks like this:

NSUInteger wordCount = [[someString componentsSeparatedByString:@" "] count];

This is not exactly correct (see @"___" where underscore is a space), but maybe you really use a regex and split on \s+?

zoul
Thanks! You hit a really good point.
Unikorn
+3  A: 

Unless you're going to be doing it hundreds of times a second, I would just opt for the readable solution, something like the following pseudocode:

def count (str):
    lastchar = " "
    count = 0
    for char as every character in string:
        if char is not whitespace and lastchar is whitespace:
            count = count + 1
        lastchar = char
    return count

It seems a bit of a waste to create a whole array of other strings just so you can count them and throw them away.

And if, for some reason, it becomes an issue, you can just replace the function body with a faster version. Make sure it is a problem first however. Optimisation of code that's fast enough already is wasted effort.

paxdiablo
Thanks for the detail reply! I think I will grab the char pointer and count the chars.
Unikorn
A: 

for storing string into an array

NSArray *yourArray = [str componentsSeparatedByString:@" "];

Update:

and to count no of word you can use

[yourArray count]
Gyani
The questioner says in the question that this is what he is already doing.
Peter Hosey
Yeah, I was doing that and find it a bit wasteful to create an array just to count and throw away. Thanks!
Unikorn
+2  A: 

There are two ways that don't involve collecting an array of words, and should be smarter than just breaking on spaces:

I would use one of these, even if I did want to collect or otherwise use the words.

Peter Hosey
Thanks Peter! I didn't know there was a CFStringTokenizer and is good to know. The reason I didn't want to use NSRegularExpression was because of the IOS 4 only limitation.
Unikorn
+4  A: 

In this situation, I'd use an NSScanner like so:

NSString *str = @"this is a string";
NSScanner *scanner = [NSScanner scannerWithString:str];
NSCharacterSet *whiteSpace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSCharacterSet *nonWhitespace = [whiteSpace invertedSet];
int wordcount = 0;

while(![scanner isAtEnd])
{
    [scanner scanUpToCharactersFromSet:nonWhitespace intoString:nil];
    [scanner scanUpToCharactersFromSet:whitespace intoString:nil];
    wordcount++;
}

This only creates two additional objects, no matter how long the string is.

NSResponder
Thanks! One question and I hope it doesn't sound stupid to you. What's does the -0 do in int wordcount -0?
Unikorn
I think that should probably be `int wordcount = 0;`. I'll fix it, NSResponder can change it back if I was wrong.
paxdiablo
Hmm... Thought I'd fixed that typo before I posted this. Oops.
NSResponder