Objective-C: -[NSString wordCount]

后端 未结 7 1184
孤街浪徒
孤街浪徒 2020-12-05 21:39

What\'s a simple implementation of the following NSString category method that returns the number of words in self, where words are separated by an

相关标签:
7条回答
  • 2020-12-05 21:50

    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].

    0 讨论(0)
  • 2020-12-05 21:54

    A Objective-C one-liner version

    NSInteger wordCount = word ? ([word stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet.invertedSet].length + 1) : 0;
    
    0 讨论(0)
  • 2020-12-05 21:56
    - (NSUInteger) wordCount
    {
       NSArray *words = [self componentsSeparatedByString:@" "];
       return [words count];
    }
    
    0 讨论(0)
  • 2020-12-05 21:59

    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
    
    0 讨论(0)
  • 2020-12-05 21:59

    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.

    0 讨论(0)
  • 2020-12-05 22:01

    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];
    }
    
    0 讨论(0)
提交回复
热议问题