2

I have a NSArray of 'generic Objects' which contain the following properties

-name
-id
-type (question, topic or user)

How can I sort this array of generic object based on the generic object's type? E.g. I want to display all generic objects of type 'topic' on the top, followed by 'users' than 'questions'

Zhen
  • 12,361
  • 38
  • 122
  • 199
  • This has been answered several times: [here](http://stackoverflow.com/questions/1351182/how-to-sort-a-nsarray-alphabetically), [here](http://stackoverflow.com/questions/805547/how-to-sort-an-nsmutablearray-with-custom-objects-in-it), and [here](http://stackoverflow.com/questions/1844031/how-to-sort-nsmutablearray-using-sortedarrayusingdescriptors), for example. – user1118321 Jan 09 '12 at 02:48
  • This question might have your answer: [link](http://stackoverflow.com/questions/805547/how-to-sort-an-nsmutablearray-with-custom-objects-in-it) – jonkroll Jan 09 '12 at 02:49
  • Thanks, but in my case, I want specifically to push all objects with type = topic to the top so I can't really use ascending or descending sort in this case I guess. How can I do that? – Zhen Jan 09 '12 at 02:58

1 Answers1

5

You'll need to define a custom sorting function, then pass it to an NSArray method that allows custom sorting. For example, using sortedArrayUsingFunction:context:, you might write (assuming your types are NSString instances):

NSInteger customSort(id obj1, id obj2, void *context) {
    NSString * type1 = [obj1 type];
    NSString * type2 = [obj2 type];

    NSArray * order = [NSArray arrayWithObjects:@"topic", @"users", @"questions", nil];

    if([type1 isEqualToString:type2]) {
        return NSOrderedSame; // same type
    } else if([order indexOfObject:type1] < [order indexOfObject:type2]) {
        return NSOrderedDescending; // the first type is preferred
    } else {
        return NSOrderedAscending; // the second type is preferred
    }   
}   

// later...

NSArray * sortedArray = [myGenericArray sortedArrayUsingFunction:customSort
                                                         context:NULL];

If your types aren't NSStrings, then just adapt the function as needed - you could replace the strings in the order array with your actual objects, or (if your types are part of an enumeration) do direct comparison and eliminate the order array entirely.

Tim
  • 59,527
  • 19
  • 156
  • 165
  • 2
    You can also use NSArray's `sortedArrayUsingComparator:` method, which takes a block as its argument. That avoids needing to write a custom function, because you can put the same comparison code inside the block. – Andrew Madsen Jan 09 '12 at 03:03
  • @AndrewMadsen: good point, thanks! There's actually a whole slew (well, five) similar comparison functions on NSArray - I picked this one pretty arbitrarily. Zhen: use whichever you're most comfortable with. – Tim Jan 09 '12 at 03:05