sort NSInteger using sortUsingComparator

14,116

Solution 1

[unsortedArray sortUsingComparator:^ NSComparisonResult(SearchResultItem *d1, SearchResultItem *d2) {
    NSInteger doorID1 = d1.doorID;
    NSInteger doorID2 = d2.doorID;
    if (doorID1 < doorID2)
        return NSOrderedAscending;
    if (doorID1 > doorID2)
        return NSOrderedDescending;
    return [d1.handel localizedCompare: d2.handel];
}];

as [aString localizedCompare:anotherString] will return NSOrdered(Ascending|Descending|same), you can just return its result for the string case.

Solution 2

An NSInteger is not an object. It is just an integer (either an int or a long). So you can compare them exactly how you would compare two ints.

Classic C comparison functions allow you to do the x - y trick, but that's not appropriate here since you'd be returning an integer that doesn't fit into the NSComparisonResult enum. As such, you should probably just do something like

if (DoorID1 == DoorID2) {
    // compare secondary attribute
    NSString *handel1 = d1.handel;
    NSString *handel2 = d2.handel;
    return [handel1 localizedCompare:handel2];
}
else if (DoorID1 < DoorID2) return NSOrderedAscending;
else return NSOrderedDescending;

Incidentally, your sorting criteria can be represented with NSSortDescriptor instead, which may be clearer.

- (NSMutableArray *)startSortingTheArray:(NSMutableArray *)unsortedArray {
    NSSortDescriptor *primary = [NSSortDescriptor sortDescriptorWithKey:@"doorID" ascending:YES];
    NSSortDescriptor *secondary = [NSSortDescriptor sortDescriptorWithKey:@"handel" ascending:YES selector:@selector(localizedCompare:)];
    [unsortedArray sortUsingDescriptors:@[primary, secondary]];
}

Solution 3

Another option:

NSComparisionResult res = [@(d1.doorID) compare:@(d2.doorID)];
return res == NSOrderedSame ? [d1.handel localizedCompare: d2.handel] : res;

Solution 4

[unsortedArray sortUsingComparator:^ NSComparisonResult(SearchResultItem *d1, SearchResultItem *d2) {
    NSInteger doorID1 = d1.doorID;
    NSInteger doorID2 = d2.doorID;
    if (doorID1 > doorID2)
        return NSOrderedAscending;
    if (doorID1 < doorID2)
        return NSOrderedDescending;
    if (doorID1==doorID2) {
        NSString *s1=d1.someString;
        NSString *s2=d2.someString;
        return [s1 compare:s2];
    }
}
Share:
14,116
HurkNburkS
Author by

HurkNburkS

DO WORK!

Updated on June 22, 2022

Comments

  • HurkNburkS
    HurkNburkS almost 2 years

    I am trying to sort an array of NSObjects (a object is of a class). The object class has several variables which I am wanting to use to sort the objects in the array, the variables I am using to sort are of type NSString or NSInteger, I am confident I am sorting NSStrings but for this question I am hoping to get help for sorting a NSInteger.

    This is the method I am using to sort the array of objects, It receives an NSMutableArray of objects

    - (NSMutableArray *)startSortingTheArray:(NSMutableArray *)unsortedArray
    {
        [unsortedArray sortUsingComparator:^ NSComparisonResult(SearchResultItem *d1, SearchResultItem *d2) {
            NSInteger DoorID1 = d1.doorID;
            NSInteger DoorID2 = d2.doorID;
            NSComparisonResult result = [DoorID1 localizedCompare:DoorID2]; // Not sure how to sort these two integers
            if (result == NSOrderedSame) {
                NSString *handel1 = d1.handel;
                NSString *handel2 = d2.handel;
                result = [handel1 localizedCompare:handel2];
             }
    

    I am not sure how to compare the NSInteger, I have read that I could minus each number from itself.. if the number is 0 then they are equal or +1 / -1 etc they are not.. but not sure if thats the best way to approach this.

    any help would be appreciated.

  • HurkNburkS
    HurkNburkS almost 12 years
    say for instance I have to move onto the next if statment for the string if NSOrderedSame then how do I do that? where dose return return too?
  • HurkNburkS
    HurkNburkS almost 12 years
    If NSOrderedSame occurs how to I step onto the next section of code ? (i.e. compare a string) as I am not sure where return is returning from...
  • HurkNburkS
    HurkNburkS almost 12 years
    okay I understand whats happening here.. will give this ago now.. :) will let you know how I get on :P
  • Lily Ballard
    Lily Ballard almost 12 years
    @HurkNburkS: The return is returning from the block.
  • vikingosegundo
    vikingosegundo almost 12 years
    note that the last if statement is not necessary, as the integers must be equal. in fact this might lead to a warning or error, as the compiler must assume, that none return statement will be reached — what is impossible.
  • HurkNburkS
    HurkNburkS almost 12 years
    with regards to your sort descriptor, how dose that work? dose it sort the array based on primary first then secondary? also dose it account for NSString or NSInteger types?
  • Bogdan Andresyuk
    Bogdan Andresyuk almost 12 years
    You`re right, its late here..just wanted to show to HurkNburkS how this all works, as he could not get the point of last return statement
  • HurkNburkS
    HurkNburkS almost 12 years
    okay thank you.. I kinda see what your doing here.. however I think my problem stems from the fact I am trying to sort based on several different if variables, a mixture of NSString and NSInteger, so I am trying to figure out the format of how you have written your solution based on more variables than just the two.
  • vikingosegundo
    vikingosegundo almost 12 years
    just do it with nested if-statements. You dont need to return immediately.
  • HurkNburkS
    HurkNburkS almost 12 years
    @vikingosegundo yes for this example you are correct, however It is actually what I need as I have several other variables I am sorting with not just the two in my example. so it is actually useful if I want to move onto checking more variables
  • HurkNburkS
    HurkNburkS almost 12 years
    okay.. I am currently working on a solution based off everyones help atm.. so will come back with an answer shortly.
  • HurkNburkS
    HurkNburkS almost 12 years
    Okay it seems to be working.. I have to run more tests on it but looks like it's sorted.. this post helped me the most so far thats why I have selected it...
  • Lily Ballard
    Lily Ballard almost 12 years
    @HurkNburkS: Yes, it sorts by the first sort descriptor, and only goes to the next one if the first one returned NSOrderedSame. It also uses -valueForKey: internally, which will automatically wrap NSIntegers in NSNumbers, which supports -compare:. The first sort descriptor will use -compare: implicitly, the second one is explicitly using -localizedCompare:.
  • terphi
    terphi about 11 years
    @vikingosegundo I think you have the NSOrderedAscending and NSOrderedDescending cases mixed up. I had to reverse them to get the correct insertion index for the NSBinarySearchingInsertionIndex case.