Call a method on every word in NSString

倾然丶 夕夏残阳落幕 提交于 2019-12-04 09:40:47

The two ways I know of looping an array that will work for you are as follows:

NSArray *words = [sentence componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

for (NSString *word in words)
{
    NSString *transformedWord = [obj method:word];
}

and

NSArray *words = [sentence componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

[words enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id word, NSUInteger idx, BOOL *stop){
    NSString *transformedWord = [obj method:word];
}];

The other method, –makeObjectsPerformSelector:withObject:, won't work for you. It expects to be able to call [word method:obj] which is backwards from what you expect.

To enumerate the words in a string, you should use -[NSString enumerateSubstringsInRange:options:usingBlock:] with NSStringEnumerationByWords and NSStringEnumerationLocalized. All of the other methods listed use a means of identifying words which may not be locale-appropriate or correspond to the system definition. For example, two words separated by a comma but not whitespace (e.g. "foo,bar") would not be treated as separate words by any of the other answers, but they are in Cocoa text views.

[aString enumerateSubstringsInRange:NSMakeRange(0, [aString length])
                            options:NSStringEnumerationByWords | NSStringEnumerationLocalized
                         usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){
    if ([substring rangeOfString:@"ll" options:NSCaseInsensitiveSearch].location != NSNotFound)
        /* do whatever */;
}];

As documented for -enumerateSubstringsInRange:options:usingBlock:, if you call it on a mutable string, you can safely mutate the string being enumerated within the enclosingRange. So, if you want to replace the matching words, you can with something like [aString replaceCharactersInRange:substringRange withString:replacementString].

If you could write your criteria with regular expressions, then you could probably do a regular expression matching to fetch these words and then pass them to your convert: method.

You could also do a split of string into an array of words using componentsSeparatedByString: or componentsSeparatedByCharactersInSet:, then go over the words in the array and detect if they fit your criteria somehow. If they fit, then pass them to convert:.

Hope this helps.

I would recommend using a while loop to go through the string like this.

NSRange spaceRange = [sentenceContainingWords rangeOfString:@" "];
NSRange previousRange = (NSRange){0,0};
do {
   NSString *wordString;
   wordString = [sentenceContainingWord substringWithRange:(NSRange){previousRange.location+1,(spaceRange.location-1)-(previousRange.location+1)}];
   //use the +1's to not include the spaces in the strings
   [self convert:wordString];
   previousRange = spaceRange;
   spaceRange = [sentenceContainingWords rangeOfString:@" "];
} while(spaceRange.location != NSNotFound);

This code would probably need to be rewritten because its pretty rough, but you should get the idea.

Edit: Just saw Jacob Gorban's post, you should definitely do it like that.

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