Quel est le moyen le plus efficace de countr le nombre de mots dans NSSsortingng sans utiliser regex?

Je suis un peu nouveau à l'objective C et je me demandais s'il y avait une meilleure façon de countr les mots dans une string.

c'est à dire:

NSSsortingng *str = @"this is a ssortingng"; // return should be 4 words .. 

La façon dont je vais maintenant le faire est de casser la string en un espace de mots ('') et de countr le tableau.

N'importe quel conseil sera apprécié! Merci!! 🙂

EDIT: Pour ceux d'entre vous qui sont venus ici à la search de réponse; J'ai trouvé un post similaire avec une excellente réponse.

Comment countr les mots dans une string de text?

Sauf si vous allez le faire des centaines de fois par seconde, j'opterais simplement pour la solution lisible, quelque chose comme le pseudo-code suivant:

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

Il semble un peu un gâchis de créer toute une gamme d'autres strings juste pour que vous puissiez les countr et les jeter.

Et si, pour une raison quelconque, cela devient un problème, vous pouvez simplement replace le corps de la fonction par une version plus rapide. Assurez-vous toutefois que c'est un problème. L'optimization du code qui est déjà assez rapide est un effort inutile.

Il y a deux manières qui n'impliquent pas la collecte d'un tableau de mots, et devraient être plus intelligentes que de simplement casser des espaces:

  • EnumerateSubssortingngsInRange de NSSsortingng enumerateSubssortingngsInRange:options:usingBlock: méthode . Présenté à Cocoa Touch dans iOS 4.0.
  • CFSsortingngTokenizer .

J'utiliserais l'un d'entre eux, même si je voulais collecter ou utiliser les mots.

Êtes-vous sûr d'avoir un goulot d'étranglement dans cette partie du code? Sinon (ce qui est assez probable), alors la division sur les espaces me semble parfaitement acceptable. Vous pouvez créer une string C et countr les espaces à la place, mais beaucoup de fois cette version "optimisée" est en réalité plus lente que celle d'origine. Autrement dit, en supposant que votre code actuel ressemble à ceci:

 NSUInteger wordCount = [[someSsortingng componentsSeparatedBySsortingng:@" "] count]; 

Ce n'est pas exactement correct (voir @"___" où underscore est un espace), mais peut-être que vous utilisez vraiment une regex et split sur \s+ ?

Dans cette situation, j'utiliserais un NSScanner comme ça:

 NSSsortingng *str = @"this is a ssortingng"; NSScanner *scanner = [NSScanner scannerWithSsortingng:str]; NSCharacterSet *whiteSpace = [NSCharacterSet whitespaceAndNewlineCharacterSet]; NSCharacterSet *nonWhitespace = [whiteSpace invertedSet]; int wordcount = 0; while(![scanner isAtEnd]) { [scanner scanUpToCharactersFromSet:nonWhitespace intoSsortingng:nil]; [scanner scanUpToCharactersFromSet:whitespace intoSsortingng:nil]; wordcount++; } 

Cela crée uniquement deux objects supplémentaires, quelle que soit la longueur de la string.

pour stocker la string dans un tableau

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

Mettre à jour:

et pour ne countr aucun mot que vous pouvez utiliser

 [yourArray count] 

Ce code countra le nombre de mots (c.-à-d., Sous-strings non vides) contenus dans une string séparés par un nombre quelconque de caractères espace ou saut de ligne :

 NSUInteger wordCount = 0; for (NSSsortingng* word in [someSsortingng componentsSeparatedByCharactersInSet: [NSMutableCharacterSet characterSetWithCharactersInSsortingng:@" \n"]]) { if (![word isEqual: @""]) { wordCount++; } } 

C'est une légère amélioration de la réponse de zoul sans revenir aux expressions régulières.

Une solution précise de revêtement:

 return [[self componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length > 0"]].count;