15

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

Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140
baste
  • 827
  • 2
  • 9
  • 18
  • Could you post more sample code? Perhaps post the `compare:` method. – jakenberg Jan 26 '13 at 20:53
  • i don't have compare method, its very strange that it sort in ascending order, what i read that ascending is the default order in sortUsingSelector. do you have an example of method that can arrange the date in descending order? thank you – baste Jan 26 '13 at 20:57
  • Look at @AKV answer. The `NSSortDescriptor` is what you're looking for. Just set ascending to NO like he did in the answer. – jakenberg Jan 26 '13 at 20:58

6 Answers6

38

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];
Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140
20

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;
Julian
  • 9,299
  • 5
  • 48
  • 65
vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
  • 2
    I'd suggest that, for readability's sake, the block be more explicit. Perhaps check if it's `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. – Carl Veazey Jan 26 '13 at 22:05
  • 1
    i try to understand your solution but i am new in ios and i cannot follow. sorry where will i place this? i load my array from dictionary in viewDidload – baste Jan 26 '13 at 23:18
  • Wehre u u need it. U can just write it to a instanc variable. If u need more help show us all relevant code – vikingosegundo Jan 27 '13 at 00:29
  • @ikinci viking, In my Array have 50 date objects, in this case how can i compare and sort it? – Ganesh G May 31 '13 at 06:45
  • @G.Ganesh: just like you would with 2,5 or 5000 – vikingosegundo May 31 '13 at 08:21
2

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.

sarbuLopex
  • 1,777
  • 1
  • 15
  • 22
1

There is the swift solution for the checked solution :

let sortedArray = randomArray.sortedArrayUsingComparator { (d1, d2) -> NSComparisonResult in
    return (d1 as! NSDate).compare(d2 as! NSDate)
}
Kevin ABRIOUX
  • 16,507
  • 12
  • 93
  • 99
1

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

Community
  • 1
  • 1
Daniel
  • 2,028
  • 20
  • 18
0

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];
jacai
  • 11
  • 2