-3

i am trying to sort a dictionary's keys. I am trying to do that using the code that is shown above but i am doing something wrong.

 self.tableInfoDictionary = [responseObject objectForKey:@"Division 4 A Herrar"];

 self.ranksSorted = [self.tableInfoDictionary allKeys];

 NSLog(@"%@", self.ranksSorted);

 self.ranksSorted = [[self.tableInfoDictionary allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

 NSLog(@"-------------------------%@", self.ranksSorted);

the output looks like this: WHY are 10 not where they are supposed to be?

2015-04-24 19:06:24.884 GBGLiveScore[14574:418925] (
    10,
    2,
    3,
    11,
    4,
    5,
    6,
    7,
    0,
    8,
    1,
    9
)
2015-04-24 19:06:24.885 GBGLiveScore[14574:418925] -------------------------(
    0,
    1,
    10,
    11,
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9
)
rmaddy
  • 314,917
  • 42
  • 532
  • 579
hamzah
  • 375
  • 2
  • 5
  • 17
  • 2
    they are in the right place, if you're using `localizedCaseInsensitiveCompare:` because it assumes the values are strings, and in a string example of `f, a, aa, b, ab, c, d, e,` it's going to be ordered as `a, aa, ab, b, c, d, e`. Use `compare:` and use the number's numerical values – Louis Tur Apr 24 '15 at 17:21
  • "and use the numbers numerical values" i tried using compare but did not work, is there something more to it? – hamzah Apr 24 '15 at 17:24
  • 1
    `[[self.tableInfoDictionary allKeys] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {return [obj1 compare:obj2 options:NSNumericSearch];}];` – Larme Apr 24 '15 at 17:31

2 Answers2

2

They're strings, and they're in lexicographical order. The string "10" comes before "2" because it compares the first characters, "1" and "2", and "1" comes before "2".

If you want them to be sorted like numbers, you'll first have to convert them to numbers, or you'll have to write a custom sort method and use that instead.

mipadi
  • 398,885
  • 90
  • 523
  • 479
2

EDITED: updates comparison block to use compare:options as commented by @Larme, much cleaner this way

This is a rough example of what you're looking to accomplish:

NSDictionary *indexedDictionary = @{ @"10": @"value10",
                                     @"14": @"value14",
                                     @"13": @"value13",
                                     @"6": @"value6",
                                     @"7": @"value7",
                                     @"2": @"value2",
                                     @"1": @"value1",
                                     @"3": @"value3",
                                     @"4": @"value4",
                                     @"8": @"value8",
                                     @"11": @"value11"
                                    };
NSArray *allIndexedKeys = [indexedDictionary allKeys];
NSArray *allSortedKeys = [allIndexedKeys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [obj1 compare:obj2 options:NSNumericSearch];
}];
NSLog(@"Sorted: %@", allSortedKeys);

Results in the following output:

2015-04-24 13:36:37.066 StackExchangeScratch[3277:389379] Sorted: (
    1,
    2,
    3,
    4,
    6,
    7,
    8,
    10,
    11,
    13,
    14
)

With each value returned being of type string, so no further conversion is needed.

Louis Tur
  • 1,303
  • 10
  • 16