views:

184

answers:

5

Hey guys, I have an NSArray of NSNumber objects that I have successfully sorted in ascending order using the following:

[myArray sortedArrayUsingSelector:@selector(compare:)]

However, I need to sort this in descending order. I take it that compare: only sorts in ascending order. While I can go about reversing the NSArray, I am curious as to whether or not there is a more simpler or more effective way of going about doing this.

Thanks!

EDIT: I found this question which provides a simple way to reverse iterate an NSArray:

for (id someObject in [myArray reverseObjectEnumerator])

This works fine, I guess it's a nice simple solution, but I'm curious as to whether or not there is a way to specify sorting in descending order.

+1  A: 

Another way, imo, is also nice: write another reverseCompare with category:

@implementation NSNumber (Utility)

- (NSComparisonResult)reverseCompare:(NSNumber *)aNumber {
  return [aNumber compare:self];
}

The good thing is that you can reuse everywhere and don't have to write the loop with reverse iterate. The bad thing is that you have to write more code:)

vodkhang
A: 

comare selector has to return NSComparisonResult. It's actually your function, so you can write another function, that returns the opposite result to sort in descending order.

Nava Carmon
Not necessarily. If the objects are instances of a built-in Cocoa class (such as NSString), you would have to category your custom comparison method onto the class.
Peter Hosey
+3  A: 

There are a few ways:

  1. Write a comparison function and pass it to sortUsingFunction:context:.
  2. Use sortUsingComparator:, which takes a block. (Only available in Mac OS X 10.6 and later and iOS 4.0 and later.)
  3. Use sortUsingDescriptors:, and pass an array of at least one sort descriptor whose ascending property is false.

In the first two cases, your comparison should simply return the negation of what the comparator you normally use (e.g., compare:) returned. The last one involves less custom code, so it's what I'd use.

Peter Hosey
+3  A: 

Use a sort descriptor

NSSortDescriptor* sortOrder = [NSSortDescriptor sortDescriptorWithKey: @"self" ascending: NO];
return [myArray sortedArrayUsingDescriptors: [NSArray arrayWithObject: sortOrder]];
JeremyP
Thanks. I ended up using this and I like how it's really simple.
Jorge Israel Peña
@Blaenk: Hi, I've rolled back your edit because `arrayWithObject:` was not a typo. There really is such a method for NSArray. Also, the spaces after the colons are deliberate.
JeremyP
The typo was that you had arayWithObject, not arrayWithObject. Then I got carried away. But that's fine.
Jorge Israel Peña
+1  A: 

The Dr. Touch website has a nice implementation of a category on NSArray to create a self-sorting array. This could be modified to keep the sort in whatever order was appropriate.

gnuchu