简体   繁体   中英

Sort an NSArray in Descending Order

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.

Use a sort descriptor

NSSortDescriptor* sortOrder = [NSSortDescriptor sortDescriptorWithKey: @"self" 
                                                            ascending: NO];
return [myArray sortedArrayUsingDescriptors: [NSArray arrayWithObject: sortOrder]];

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

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

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 (eg, compare: ) returned. The last one involves less custom code, so it's what I'd use.

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];

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

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.

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.

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];

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.

Use the following code to sort Array on the basis of key on which you want to sort tge array (eg 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];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM