-1

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.

zztop
  • 701
  • 1
  • 7
  • 20
  • You can get the word count as described here: https://stackoverflow.com/questions/6171422/objective-c-nsstring-wordcount – koen Oct 03 '18 at 21:19

4 Answers4

1

I have an array of strings that I would like to sort by the number of words in each string

First write a utility method that takes a string and returns the number of words in it (whatever that means to you). Then call sortedArrayUsingComparator: to sort your array of strings based on the result of calling the utility method on each element.

matt
  • 515,959
  • 87
  • 875
  • 1,141
1

A simple implementation (assuming the words in your sentences are separated by a space) could look like this:

// create a comparator
NSComparisonResult (^comparator)(NSString *, NSString *) = ^ (NSString *firstString, NSString *secondString){
    NSUInteger numberOfWordsInFirstString = [firstString componentsSeparatedByString:@" "].count;
    NSUInteger numberOfWordsInSecondString = [secondString componentsSeparatedByString:@" "].count;

    if (numberOfWordsInFirstString > numberOfWordsInSecondString) {
        return NSOrderedDescending;
    } else if (numberOfWordsInFirstString < numberOfWordsInSecondString) {
        return NSOrderedAscending;
    } else {
        return NSOrderedSame;
    }
};

NSArray *strings = @[@"a word", @"even more words", @"a lot of words", @"more words", @"i can't even count the words"];

// use the comparator to sort your array of strings
NSArray *stringsSortedByNumberOfWords = [strings sortedArrayUsingComparator:comparator];
NSLog(@"%@", stringsSortedByNumberOfWords);

// results in:
// "a word",
// "more words",
// "even more words",
// "a lot of words",
// "i can't even count the words"
André Slotta
  • 13,774
  • 2
  • 22
  • 34
1

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]];
Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50
  • the code compiles but trying to access wordCount (or WordCount) is throwing an unrecognized selector exception – zztop Oct 04 '18 at 13:55
  • Got it to work going with one of the word count methods in the link provided by Koen. Issue was since wordCount is a method on NSString it needs to reference self for string, not String as an argument. In Amin's method I think you'd change to self as well. – zztop Oct 04 '18 at 19:02
  • Oh, yeah, … I changed it. – Amin Negm-Awad Oct 09 '18 at 11:06
-2

Here is the Objective-C code

NSArray *myWordGroups = @[@"three",@"one two three",@"one two"];

NSArray *sortedStrings = [myWordGroups sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"self.length" ascending:YES]]];
// => Sorted Array : @[@"three", @"one two", @"one two three"]
Satish
  • 2,015
  • 1
  • 14
  • 22