How Do I sort an NSMutable Array with NSNumbers in it?

IphoneObjective CArrays

Iphone Problem Overview


I'm trying to make a high score table, and suck at arrays in objective c (actually, in general objective c is challenging for me), so I can't figure out how to sort. I'm trying to do something like this (speudocode, I'm writing this in actionscript style because I'm more comfortable with it):

highscores.addObjecttoArray(score)
highscores.sort(ascending)

But I can't figure it out... I've seen other threads about it, but their use plist files and stuff and I don't know enough objective c to learn from them.

Iphone Solutions


Solution 1 - Iphone

Would you like to do that the short way?

If you have a mutable array of NSNumber instances:

NSSortDescriptor *highestToLowest = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:NO];
[mutableArrayOfNumbers sortUsingDescriptors:[NSArray arrayWithObject:highestToLowest]];

Nice and easy :)

You can also perform similar sorting with descriptors on immutable arrays, but you will end up with a copy, instead of in-place sorting.

Solution 2 - Iphone

[highscores sortUsingSelector:@selector(compare:)];

Should work if they're definitely all NSNumbers.

(Adding an object is:

[highscores addObject:score];

)

If you want to sort descending (highest-first):

10.6/iOS 4:

[highscores sortUsingComparator:^(id obj1, id obj2) {
    if (obj1 > obj2)
        return NSOrderedAscending;
    else if (obj1 < obj2)
        return NSOrderedDescending;

    return NSOrderedSame;
}];

Otherwise you can define a category method, e.g.:

@interface NSNumber (CustomSorting)

- (NSComparisonResult)reverseCompare:(NSNumber *)otherNumber;

@end

@implementation NSMutableArray (CustomSorting)

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

@end

And call it:

[highscores sortUsingSelector:@selector(reverseCompare:)];

Solution 3 - Iphone

I tried the answer provided by ohhorob, but the objects were still being sorted alphabetically. Then I ran across this in another answer (https://stackoverflow.com/a/4550451/823356):

I changed my NSSortDescriptor and it now sorts numerically.

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"score"
                                               ascending:YES
                                              comparator:^(id obj1, id obj2) {
    return [obj1 compare:obj2 options:NSNumericSearch];
}];

I just thought I'd drop this in here as it solved my 'alphabetical sorting of NSNumbers' problem

Solution 4 - Iphone

For all it's worth, here is another shorthand method:

NSArray* n = @[@8, @3, @1, @12, @16, @7, @0, @5];

NSArray* asc = [n sortedArrayUsingComparator:^NSComparisonResult(NSNumber* n1, NSNumber* n2) {
            return [n1 compare:n2];
        }];
NSLog(@"Ascending: %@", asc);

NSArray* dec = [n sortedArrayUsingComparator:^NSComparisonResult(NSNumber* n1, NSNumber* n2) {
           return [n2 compare:n1];
       }];
NSLog(@"Descending: %@", dec);

Solution 5 - Iphone

This code will sort an NSMutableArray of NSNumber in ascending order:

[tempRA sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [obj1 compare:obj2];
}];

This code will sort an NSMutableArray of NSNumber in descending order:

[tempRA sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [obj1 compare:obj2] * -1; // reverse the enum
}];

The code uses the fact that the NSNumber compare: method returns an NSComparisonResult that ranges from -1 to 1. Multiplying the result of the compare by -1 reverses the result and thereby reverses the sort to descending order.

Solution 6 - Iphone

distance is a key and it's value link (float or double)

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"distance"
ascending:YES
comparator:^(id obj1, id obj2)
                     {
                  return [obj1 compare:obj2 options:NSNumericSearch];
                     }];
NSArray *myArray = [NSArray arrayWithArray:arraySubCat];
myArray=[myArray sortedArrayUsingDescriptors:[NSArray arrayWithObjects:sortDescriptor,nil]];
arraySubCat = [myArray copy];

Solution 7 - Iphone

For Descending Order:

NSArray *DescendingArray = [MinMaxArray sortedArrayUsingDescriptors:
                                @[[NSSortDescriptor sortDescriptorWithKey:@"doubleValue"
                                                                ascending:NO]]];

For ascending Order

NSArray *AscendingArray = [MinMaxArray sortedArrayUsingDescriptors:
                                @[[NSSortDescriptor sortDescriptorWithKey:@"doubleValue"
                                                                ascending:YES]]];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionmeman32View Question on Stackoverflow
Solution 1 - IphoneohhorobView Answer on Stackoverflow
Solution 2 - IphoneWevahView Answer on Stackoverflow
Solution 3 - IphonethereleventfridgeView Answer on Stackoverflow
Solution 4 - IphoneMike MView Answer on Stackoverflow
Solution 5 - Iphoneuser3641723View Answer on Stackoverflow
Solution 6 - IphoneRahul PatelView Answer on Stackoverflow
Solution 7 - IphoneRamdhasView Answer on Stackoverflow