I have a NSDictionary that parsed to an array one of the element is date, i tried using [startimeArray sortUsingSelector:@selector(compare:)]; (starttimeArray) is my date but it only arrange ascending. how can i sort in descending order. thanks
6 Answers
Sort the array by puting NO is ascending parameter:
NSSortDescriptor *descriptor=[[NSSortDescriptor alloc] initWithKey:@"self" ascending:NO];
NSArray *descriptors=[NSArray arrayWithObject: descriptor];
NSArray *reverseOrder=[dateArray sortedArrayUsingDescriptors:descriptors];
    3 Comments
You can use a comparator block
NSArray *sortedArray = [array sortedArrayUsingComparator: ^(NSDate *d1, NSDate *d2) {
    return [d1 compare:d2];
}];
to reverse the order, just swap the dates
NSArray *sortedArray = [array sortedArrayUsingComparator: ^(NSDate *d1, NSDate *d2) {
    return [d2 compare:d1];
}];
or — as compare: returns a NSComparisonResult, which is actually typedef'ed to integer see below — just multiply by -1
NSArray *sortedArray = [array sortedArrayUsingComparator: ^(NSDate *d1, NSDate *d2) {
    return -1* [d1 compare:d2];
}];
enum {
   NSOrderedAscending = -1,
   NSOrderedSame,
   NSOrderedDescending
};
typedef NSInteger NSComparisonResult;
    5 Comments
NSOrderedAscending and set to NSOrderedDescending explicitly, and vice versa. Both of the approaches (switching the argument order and multiplying by -1) strike me as depending too much on implementation details and not being clear to future readers.I'd use the built-in reverseObjectEnumerator method of NSArray
startimeArray = [startimeArray sortUsingSelector:@selector(compare:)];
startimeArray = [[startimeArray reverseObjectEnumerator] allObjects];
It's useful when you need the array sorted in ascending and descending order, so you can easily go back to the previous sort.
Comments
Swift 3.0
For anyone using swift 3.0 this DateHelper will save u some headache.
   filteredLogs.sort(by: {
        let firstElement = $0.timeStamp! as Date
        let secondElement = $1.timeStamp! as Date
        return firstElement.compare(.isEarlier(than: secondElement))
    })
The above code is a snippet from one of my projects. It uses the helper class to sort my logs with most recent dates at the left of the array. The $ sign is a positional parameter
Comments
In the Class where the Array elements are being initialized.
-(NSComparisonResult) compareArray: (id) element {
    Return [ArrayElement compare: [element ArrayElement]];
}
-(NSComparisonResult) compareArrayReverse: (id) element {
    Return [[element ArrayElement] compare: ArrayElement];
}
Then in the Class where your startimeArray is initialized:
@synthesize ArrayName;
-(void) sort: (BOOL) sel {
    if (sel) {
        [ArrayName sortUsingSelector: @selector(compareArray:)];
    } else {
        [ArrayName sortUsingSelector: @selector(compareArrayReverse:)];
    }    
}
Then in the main():
// Sort the array. sort = TRUE - ascending order, sort = FALSE - descending order.
[startimeArray sort: FALSE];
    
compare:method.NSSortDescriptoris what you're looking for. Just set ascending to NO like he did in the answer.