Objective-C: -[NSString wordCount]

我与影子孤独终老i 提交于 2019-11-26 23:10:36

问题


What's a simple implementation of the following NSString category method that returns the number of words in self, where words are separated by any number of consecutive spaces or newline characters? Also, the string will be less than 140 characters, so in this case, I prefer simplicity & readability at the sacrifice of a bit of performance.

@interface NSString (Additions)
- (NSUInteger)wordCount;
@end

I found the following solutions:

  • implementation of -[NSString wordCount]
  • implementation of -[NSString wordCount] - seems a bit simpler

But, isn't there a simpler way?


回答1:


Why not just do the following?

- (NSUInteger)wordCount {
    NSCharacterSet *separators = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    NSArray *words = [self componentsSeparatedByCharactersInSet:separators];

    NSIndexSet *separatorIndexes = [words indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        return [obj isEqualToString:@""];
    }];

    return [words count] - [separatorIndexes count];
}



回答2:


I believe you have identified the 'simplest'. Nevertheless, to answer to your original question - "a simple implementation of the following NSString category...", and have it posted directly here for posterity:

@implementation NSString (GSBString)

- (NSUInteger)wordCount
{
    __block int words = 0;
    [self enumerateSubstringsInRange:NSMakeRange(0,self.length)
                             options:NSStringEnumerationByWords
                          usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {words++;}];
    return words;
}

@end



回答3:


There are a number of simpler implementations, but they all have tradeoffs. For example, Cocoa (but not Cocoa Touch) has word-counting baked in:

- (NSUInteger)wordCount {
    return [[NSSpellChecker sharedSpellChecker] countWordsInString:self language:nil];
}

It's also trivial to count words as accurately as the scanner simply using [[self componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] count]. But I've found the performance of that method degrades a lot for longer strings.

So it depends on the tradeoffs you want to make. I've found the absolute fastest is just to go straight-up ICU. If you want simplest, using existing code is probably simpler than writing any code at all.




回答4:


- (NSUInteger) wordCount
{
   NSArray *words = [self componentsSeparatedByString:@" "];
   return [words count];
}



回答5:


Looks like the second link I gave in my question still reigns as not only the fastest but also, in hindsight, a relatively simple implementation of -[NSString wordCount].




回答6:


A Objective-C one-liner version

NSInteger wordCount = word ? ([word stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet.invertedSet].length + 1) : 0;



回答7:


Swift 3:

let words: [Any] = (string.components(separatedBy: " "))
let count = words.count


来源:https://stackoverflow.com/questions/6171422/objective-c-nsstring-wordcount

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!