Search code examples
iosobjective-cnsarray

IOS/Objective-C: Sort NSArray of NSStrings by number of words in string


I have an array of strings that I would like to sort by the number of words in each string. I am weak, however, on dictionaries and arrays and having trouble doing this efficiently.

One way might be to place each string in a dictionary that has the string and the number of words in it and then sort the dictionaries by the number of words using NSSortDescriptor.

Something like:

NSArray *myWordGroups = @[@"three",@"one two three",@"one two"];
NSMutableArray *arrayOfDicts=[NSMutableArray new];
for (i=0;i<[myWordGroups count];i++) {
long numWords = [myWordGroups[i] count];
//insert word and number into dictionary and add dictionary to new array

}
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"numWords"
                                           ascending:NO];
NSArray *sortedArray = [myWords sortedArrayUsingDescriptors:@[sortDescriptor]];

I am unclear on the code to add the word and number of words into the dictionary. And even if I knew that code this seems awfully cumbersome.

Is there a way to quickly sort an array of Strings by the number of words in each?

Thanks in advance for any suggestions.


Solution

  • You should expand NSString with a word count method first:

    @interface NSString(WordCount)
    - (NSUInteger)wordCount;
    @end
    
    @implementation NSString(WordCount)
    - (NSUInteger)wordCount
    {
      // There are several ways to do this. Pick up your own on SO or another place of the internet. I took this one:
      __block NSUInteger count = 0;
      [self enumerateSubstringsInRange:NSMakeRange(0, string.length)
                                options:NSStringEnumerationByWords
                             usingBlock:
      ^(NSString *character, NSRange substringRange, NSRange enclosingRange, BOOL *stop) 
      {
        count++;
      }];
      return count;
    }
    

    This has advantages:

    • You can use this method for other reasons.
    • The word count is a property of a string, so the method should be a member of the class NSString.

    Now you can simply use a sort descriptor:

    NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:@"wordCount" ascending:YES];
    NSArray *sortedStrings = [myWordGroups sortedArrayUsingDescriptors:@[sorter]];