Цель-C: - [NSString wordCount] - PullRequest
6 голосов
/ 30 мая 2011

Какова простая реализация следующего метода категории NSString, который возвращает количество слов в self, где слова разделяются любым количеством последовательных пробелов или символов новой строки? Кроме того, строка будет содержать менее 140 символов, поэтому в этом случае я предпочитаю простоту и удобочитаемость, жертвуя при этом производительностью.

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

Я нашел следующие решения:

Но разве нет более простого способа?

Ответы [ 7 ]

15 голосов
/ 30 мая 2011

Почему бы просто не сделать следующее?

- (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];
}
9 голосов
/ 14 сентября 2014

Полагаю, вы определили «простейшее». Тем не менее, чтобы ответить на ваш первоначальный вопрос - «простая реализация следующей строки NSString category ...», и выложите ее прямо здесь для потомков:

@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
8 голосов
/ 30 мая 2011

Существует несколько простых реализаций, но у всех есть свои компромиссы. Например, Cocoa (но не Cocoa Touch) имеет функцию подсчета слов, запеченную в:

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

Также просто считать слова так же точно, как сканер, просто используя [[self componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] count]. Но я обнаружил, что производительность этого метода сильно ухудшается для более длинных строк.

Так что это зависит от компромиссов, которые вы хотите сделать. Я обнаружил, что самое быстрое - это просто пойти по прямой ICU . Если вы хотите самое простое, использование существующего кода, вероятно, проще, чем написание какого-либо кода вообще.

4 голосов
/ 30 мая 2011
- (NSUInteger) wordCount
{
   NSArray *words = [self componentsSeparatedByString:@" "];
   return [words count];
}
1 голос
/ 27 июля 2018

Однолинейная версия Objective-C

NSInteger wordCount = word ? ([word stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet.invertedSet].length + 1) : 0;
1 голос
/ 30 мая 2011

Похоже, что вторая ссылка, которую я дал в своем вопросе, по-прежнему не только самая быстрая, но и, задним числом, относительно простая реализация - [NSString wordCount] .

0 голосов
/ 14 сентября 2017

Swift 3:

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