7

I am attempting to sort an NSDictionary.

From the Apple docs I see you can use keysSortedByValueUsingSelector:

NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithInt:63], @"Mathematics",
    [NSNumber numberWithInt:72], @"English",
    [NSNumber numberWithInt:55], @"History",
    [NSNumber numberWithInt:49], @"Geography",
    nil];

NSArray *sortedKeysArray = [dict keysSortedByValueUsingSelector:@selector(compare:)];

which gives:

// sortedKeysArray contains: Geography, History, Mathematics, English

but I want:

// sortedKeysArray contains: English, Mathematics, History, Geography

I have read that you can use compare:options:, and an NSStringCompareOptions to change the comparison to compare in the other direction.

However I don't understand how you send compare:options: with an option in the selector.

I want to do something like this:

NSArray *sortedKeysArray = [dict keysSortedByValueUsingSelector:@selector(compare:options:NSOrderDescending)];

How should I switch the order of the comparison?

Related: https://discussions.apple.com/thread/3411089?start=0&tstart=0

ck_
  • 3,719
  • 10
  • 49
  • 76

2 Answers2

13

Option 1: Use a comparator to invoke -compare: in reverse: (Thanks Dan Shelly!)

NSArray *blockSortedKeys = [dict keysSortedByValueUsingComparator: ^(id obj1, id obj2) {
     // Switching the order of the operands reverses the sort direction
     return [objc2 compare:obj1];
}];

Just reverse the descending and ascending return statements and you should get just what you want.

Option 2: Reverse the array you have:

See How can I reverse a NSArray in Objective-C?

Community
  • 1
  • 1
paulmelnikow
  • 16,895
  • 8
  • 63
  • 114
  • or [dict keysSortedByValueUsingComparator:^NSComparisonResult(id obj1, id obj2) { return [obj2 compare:obj1]; }]; – Dan Shelly Apr 05 '13 at 04:42
  • That wouldn't reverse the array, though maybe `return -[objc2 compare:obj1]` would work. – paulmelnikow Apr 05 '13 at 04:49
  • I've tested it on a simple example ..., To be more specific, in a comparison based sort, reversing the order of comparison will reverse the resulting array – Dan Shelly Apr 05 '13 at 05:39
4

I use :

    NSSortDescriptor *sortOrder = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:NO];
    self. sortedKeys = [[self.keyedInventoryItems allKeys] sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortOrder]];
YvesLeBorg
  • 9,070
  • 8
  • 35
  • 48
  • This answer is incorrect. It sorts the keys in descending order, without reference to the values in the dictionary. @noa's answer to use the comparator is correct. – Jon Dec 16 '13 at 19:59