Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sort NSDictionary keys by dictionary value into an NSArray

I've seen a lot of examples of sorting a dictionary by keys, then getting the values, but how would I sort instead by values.

e.g.

{
blue:12;
red:50;
white:44;
}

I would want these sorted by number descending to:

{
red:50;
white:44;
blue:12
}

I tried getting a sorted nsarray of keys from which I could created the ordered nsarray but the result still seems unordered.

  NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) {

    if ( first < second ) {
        return (NSComparisonResult)NSOrderedAscending;
    } else if ( first > second ) {
        return (NSComparisonResult)NSOrderedDescending;
    } else {
        return (NSComparisonResult)NSOrderedSame;
    }

  }];
like image 279
MonkeyBonkey Avatar asked Jun 26 '12 23:06

MonkeyBonkey


People also ask

Can we sort dictionary in C#?

In C#, SortedDictionary is a generic collection which is used to store the key/value pairs in the sorted form and the sorting is done on the key. SortedDictionary is defined under System. Collection. Generic namespace.

How do you sort an array in a dictionary?

To sort a list of dictionaries according to the value of the specific key, specify the key parameter of the sort() method or the sorted() function. By specifying a function to be applied to each element of the list, it is sorted according to the result of that function.


1 Answers

Conceptually a NSDictionary is unsorted, as said already by C0deH4cker.

If you need an order, you can either write the keys to an array (but you might have trouble with the array retaining it after the key was removed from the dictionary, but there are tutorials how to create a un-retaining array by using the CFArray) or NSSortedSet.

Or you can subclass NSDictionary — not very trivial, as NSDictionary is a class cluster. But luckily Matt shows in his fantastic blogpost "OrderedDictionary: Subclassing a Cocoa class cluster" how to use a little trick, a covered has-a relationship.


Note, that your code

 NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) {

    if ( first < second ) {
        return (NSComparisonResult)NSOrderedAscending;
    } else if ( first > second ) {
        return (NSComparisonResult)NSOrderedDescending;
    } else {
        return (NSComparisonResult)NSOrderedSame;
    }

  }];

wont do, what you want it to do, as you are applying C-operators to objects. Now their pointers will be ordered.

it should be something like

 NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) {
    return [first compare:second];
  }];

or if you want to order on scalars, that are wrappers as objects (ie NSNumber)

 NSArray* sortedKeys = [stats keysSortedByValueUsingComparator:^(id first, id second) { 
    if ([first integerValue] > [second integerValue]) 
        return (NSComparisonResult)NSOrderedDescending;

    if ([first integerValue] < [second integerValue])
        return (NSComparisonResult)NSOrderedAscending;
    return (NSComparisonResult)NSOrderedSame;
}];
like image 105
vikingosegundo Avatar answered Sep 21 '22 15:09

vikingosegundo