views:

92

answers:

4

Hi there

basically I have an NSDictionary with keys and values.

The keys are all numbers, but at the moment they are strings.

I want to be able to compare them as numbers in order to sort them.

eg: If I have a Dictionary like this:

{
  "100"  => (id)object,
  "20"   => (id)object,
  "10"   => (id)object,
  "1000" => (id)object,
}

I want to be able to sort it like this:

{
  "10"   => (id)object,
  "20"   => (id)object,
  "100"  => (id)object,
  "1000" => (id)object,
}

Any ideas?

Thanks

Tom

+1  A: 

Use compare:options: with NSNumericSearch.

Ole Begemann
+4  A: 

Not sure what you are up to – dictionaries are inherently unsorted, there is no stable key ordering in the default implementation. If you want to walk the values by sorted keys, you can do something like this:

NSInteger floatSort(id num1, id num2, void *context)
{
    float v1 = [num1 floatValue];
    float v2 = [num2 floatValue];
    if (v1 < v2)
        return NSOrderedAscending;
    else if (v1 > v2)
        return NSOrderedDescending;
    else
        return NSOrderedSame;
}

NSArray *allKeys = [aDictionary allKeys];
NSArray *sortedKeys = [allKeys sortedArrayUsingFunction:floatSort context:NULL];
for (id key in sortedKeys)
    id val = [aDictionary objectForKey:key];
    …
zoul
this is what I want :) thank you. :) I tried getting `allKeys` from the dictionary, but they were still strings... and I'm not too savvy on sorting. I knew I'd have to get allKeys as an array, sort that and then output each one in the order of the array, but i wasn't sure how to sort the keys of the dictionary. thank you.
Thomas Clayson
just add one return in the end of floatSort function to avoid possible compiler warnings
Vladimir
@Vladimir: Not sure about other compilers, but at least my LLVM 1.5 is smart enough to figure out that the function always returns a value.
zoul
ok heres a question - it won't let me use nested functions. Where do I put this function so that its not nested? Or can I turn it into a class method and use `sortUsingSelector:@selector(method:)`.
Thomas Clayson
Simply put it somewhere between your methods, it will work just fine.
zoul
then i get the error that "floatSort" is undeclared. :(
Thomas Clayson
its ok... i need to out it BEFORE i call it. :p thanks
Thomas Clayson
@zoul, checked that on gcc - it really does not produce any warning. so sorry - false alarm :)
Vladimir
A: 

Already on SO:

http://stackoverflow.com/questions/2696354/how-can-i-sort-an-nsdictionary (and other similar questions)

Alin
+1  A: 

You can't sort a dictionary, but you can get the keys as an array, sort that, then output in that order. sortedArrayUsingComparator will do that, and you can compare the strings with the NSNumericSearch option.

NSArray* keys = [myDict allKeys];
NSArray* sortedArray = [keys sortedArrayUsingComparator:^(id a, id b) { 
    return [a compare:b options:NSNumericSearch]; 
}]; 

for( NSString* aStr in sortedArray ) {
    NSLog( @"%@ has key %@", [myDict objectForKey:aStr], aStr );
}
zpasternack