Reputation: 7484
I want to be able to sort a NSArray of objects based on its tag value. The hitch is if the tag is 0, I want it pushed to the end of the array.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"tag" ascending:TRUE];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [self.array sortedArrayUsingDescriptors:sortDescriptors];
This returns with all the objects with tags in the front of the index (like it should).
I want a tag value > 0 to be at the front, and all the tag values of 0 at the end.
I though blocks would work, something similar to:
NSArray *sortedArray;
sortedArray = [drinkDetails sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSDate *first = [(Person*)a birthDate];
NSDate *second = [(Person*)b birthDate];
return [first compare:second];
}];
that I found in another SO question, but unsure how to add the condition
if (obj.tag == 0) {
// push to end of array
}
Any suggestions?
Upvotes: 0
Views: 125
Reputation: 379
// sort the part without tag = 0
NSPredicate* p = [NSPredicate predicateWithFormat: @"tag != 0"];
NSSortDescriptor* sort = [NSSortDescriptor sortDescriptorWithKey: @"tag" ascending: YES];
NSMutableArray* result = [[[videos filteredArrayUsingPredicate: p]
sortedArrayUsingDescriptors: @[ sort ]] mutableCopy];
// append the part with tag = 0;
p = [NSPredicate predicateWithFormat: @"tag = 0"];
[result addObjectsFromArray: [videos filteredArrayUsingPredicate: p]];
Another approach, splice the original array to two parts, sort part without the 0s, and then append the part with 0s to the end.
Upvotes: 0
Reputation: 81132
You've found the idea of a comparator block; all you need to do in that block is say that an object with tag 0 sorts after anything else.
sortedArray = [self.array sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSInteger first = [a tag];
NSInteger second = [b tag];
if (first == 0) {
return (second == 0 ? NSOrderedSame : NSOrderedDescending);
}
if (second == 0) {
return NSOrderedAscending;
}
if (first < second) {
return NSOrderedAscending;
}
if (first > second) {
return NSOrderedDescending;
}
return NSOrderedSame;
}];
Upvotes: 4