Sort an NSArray in Descending Order
Asked Answered
T

11

38

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.

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.

Tildy answered 4/8, 2010 at 4:49 Comment(1)
This answer is short, sweet and clever: https://mcmap.net/q/47573/-how-can-i-reverse-a-nsarray-in-objective-cEpiboly
G
84

Use a sort descriptor

NSSortDescriptor* sortOrder = [NSSortDescriptor sortDescriptorWithKey: @"self" 
                                                            ascending: NO];
return [myArray sortedArrayUsingDescriptors: [NSArray arrayWithObject: sortOrder]];
Goebel answered 4/8, 2010 at 8:24 Comment(3)
Thanks. I ended up using this and I like how it's really simple.Weigle
@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.Goebel
The typo was that you had arayWithObject, not arrayWithObject. Then I got carried away. But that's fine.Weigle
E
12

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:)

Edva answered 4/8, 2010 at 5:1 Comment(0)
C
7

use sortarrayusingcomparator method like that

NSArray *sortedArray = [array sortedArrayUsingComparator:
^NSComparisonResult(id obj1, id obj2){
        return [obj2 compare:obj1];
    }];

by reversing the order of objects you will obtain a descending order

Calcium answered 12/4, 2015 at 11:27 Comment(1)
It works like a charm, I used to sort an array of NSString. You need a sorted array to apply this.Rosmunda
B
6

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.

Bashuk answered 4/8, 2010 at 5:18 Comment(0)
V
3

I have a mutableArray and want to sort in descending order with "number" key. "number" key is a string like "12345", "12346". This way that I had tried and look very well. Hope help you!

NSComparisonResult result;

NSArray *arrTem = [multableArr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    if([obj1 valueForKey:@"number"] > [obj2 valueForKey:@"number"])
         result = NSOrderedDescending;
    result = NSOrderedSame;
}];

return [[NSMutableArray alloc]initWithArray:arrTem];
Vibraharp answered 31/3, 2016 at 8:18 Comment(0)
H
2

For Example Data is Like this and we want to sort NSArray based on sId key.

<__NSArrayM 0x7ffc725af1d0>(
{
    sId = 3;
    vName = ABC;
},
{
    sId = 10;
    vName = DEF;
},
{
    sId = 9;
    vName = GHI;
},
{
    sId = 7;
    vName = JKL;
},
{
    sId = 1;
    vName = MNO;
}
)

Solution is as Below

NSArray *sortedArray = [arrOptions sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    if ([[obj1 valueForKey:@"sId"] integerValue] > [[obj2 valueForKey:@"sId"] integerValue]) {
        return (NSComparisonResult)NSOrderedDescending;
    }
    if ([[obj1 valueForKey:@"sId"] integerValue] < [[obj2 valueForKey:@"sId"] integerValue]) {
        return (NSComparisonResult)NSOrderedAscending;
    }
    return (NSComparisonResult)NSOrderedSame;
}];
NSLog(@"Sorted Service Array is ::%@",sortedArray);
Hut answered 23/9, 2015 at 9:28 Comment(0)
E
1

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.

Exaltation answered 4/8, 2010 at 5:2 Comment(1)
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.Bashuk
C
1

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.

Closet answered 4/8, 2010 at 8:50 Comment(0)
P
1

If you need based on ABCD in ascending then use following code

NSSortDescriptor *descriptor=[[NSSortDescriptor alloc] initWithKey:@"self" ascending:YES];
NSArray *descriptors=[NSArray arrayWithObject: descriptor];
NSArray *reverseOrder=[yourArray sortedArrayUsingDescriptors:descriptors];
Piraeus answered 5/3, 2015 at 4:47 Comment(0)
W
0

we can do it simply by using sortUsingSelector. The code as follows;

NSMutableArray *arr=[[NSMutableArray alloc]initWithObjects: ..objects.. ];
//Can also use NSArray.
[arr sortUsingSelector:@selector(compare:options:)];
NSString *temp;
int i,j;
i=0;
j=[arr count];
for(i=0;i<([arr count]-1);i++)
{
    temp=[arr objectAtIndex:i];
    [arr replaceObjectAtIndex:i withObject:[arr objectAtIndex:j]];
    [arr replaceObjectAtIndex:j withObject:temp];
    j--;
}
NSLog(@"New array is:%@",arr);

You may think that WHAT A STUPID ANSWER it is :D :D Actually, am not teasing anyone. But in simple logic, we can sort array in descending order by this way. No need of using any type of descriptors or any other complicated stuffs. And it will be easier for entry level programmers.

Wooded answered 5/5, 2016 at 7:59 Comment(0)
M
-1

Use the following code to sort Array on the basis of key on which you want to sort tge array (e.g name , code, address,emp_id etc...)

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Enter Sort Type" ascending:NO];

NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
return [array sortedArrayUsingDescriptors:sortDescriptors];
Musician answered 17/11, 2016 at 7:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.