sort NSInteger using sortUsingComparator
Asked Answered
S

4

7

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.

Sclerite answered 14/8, 2012 at 0:2 Comment(0)
N
20
[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.

Narwhal answered 14/8, 2012 at 0:8 Comment(6)
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?Sclerite
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.Sclerite
just do it with nested if-statements. You dont need to return immediately.Narwhal
okay.. I am currently working on a solution based off everyones help atm.. so will come back with an answer shortly.Sclerite
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...Sclerite
@Narwhal 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.Whyte
C
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]];
}
Consult answered 14/8, 2012 at 0:7 Comment(4)
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...Sclerite
@HurkNburkS: The return is returning from the block.Consult
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?Sclerite
@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:.Consult
K
2

Another option:

NSComparisionResult res = [@(d1.doorID) compare:@(d2.doorID)];
return res == NSOrderedSame ? [d1.handel localizedCompare: d2.handel] : res;
Krum answered 13/10, 2014 at 14:6 Comment(0)
C
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;
    if (doorID1==doorID2) {
        NSString *s1=d1.someString;
        NSString *s2=d2.someString;
        return [s1 compare:s2];
    }
}
Cotswold answered 14/8, 2012 at 0:35 Comment(4)
okay I understand whats happening here.. will give this ago now.. :) will let you know how I get on :PSclerite
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.Narwhal
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 statementCotswold
@Narwhal 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 variablesSclerite

© 2022 - 2024 — McMap. All rights reserved.