15

I am attempting to sort an NSArray that is populated with custom objects. Each object has a property startDateTime that is of type NSDate.

The following code results in an array, sortedEventArray, populated but not sorted. Am I going about this the completely wrong way or am I just missing something small?

NSSortDescriptor *dateDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"startDateTime" 
                                                                 ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor];
NSArray *sortedEventArray = [nodeEventArray sortedArrayUsingDescriptors:sortDescriptors];
3
  • Code seems perfectly fine. Are you sure you have the correct key? Commented May 21, 2011 at 20:47
  • @Firoze: Yes, I have triple checked the name. "startDateTime" is the name of the NSDate property on my custom class. Commented May 21, 2011 at 22:52
  • 2
    The problem turned out to be elsewhere in my code so I considered closing the question, but due to the helpful nature of the answers below, I am going to leave it here as I think others may find it useful. Commented May 22, 2011 at 16:47

5 Answers 5

25

Are you sure that the startDateTime instance variables of the node events are non-nil?

If you don't have one already, you might add a (custom) -description method to your node event objects that does something like this:

- (NSString *)description {
   return [NSString stringWithFormat:@"%@ - %@",
                   [super description], startDateTime]];
}

Then in your sorting code log the array before and after:

NSLog(@"nodeEventArray == %@", nodeEventArray);
NSSortDescriptor *dateDescriptor = [NSSortDescriptor
                                     sortDescriptorWithKey:@"startDateTime" 
                                                 ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor];
NSArray *sortedEventArray = [nodeEventArray
         sortedArrayUsingDescriptors:sortDescriptors];
NSLog(@"sortedEventArray == %@", sortedEventArray);

If the startDateTime's are all nil, then the before and after arrays will have the same order (since the sorting operation will equate to sending all the -compare: messages to nil, which basically does nothing).

Sign up to request clarification or add additional context in comments.

Comments

11

Did you try by specifying the NSDate comparator?

Eg:

NSSortDescriptor *dateDescriptor = [NSSortDescriptor
   sortDescriptorWithKey:@"startDateTime"
   ascending:YES
   selector:@selector(compare:)];

This should enforce the usage of the correct comparator of the NSDate class.

1 Comment

This change did not seem to affect my results.
11

Ok, I know this is a little late, but this is how I would do it:

NSArray *sortedEventArray = [events sortedArrayUsingComparator:^NSComparisonResult(Event *event1, Event *event2) {
    return [event1.startDateTime compare:event2.startDateTime];
}];

Obviously, replace Event with the class of your custom object. The advantage of this approach is that you are protected against future refactoring. If you were to refactor and rename the startDateTime property to something else, Xcode probably would not change the string you're passing into the sort descriptor. Suddenly, your sorting code would break/do nothing.

2 Comments

I agree with you. FYI though, small typo. It's: "sortedArrayUsingComparator:"
@PaulEvans I was using -[NSMutableArray sortUsingComparator:], as I noted in my comment. However, I can change it to return a new sorted array in line with OP's example. Thanks :)
0

You can achieve like this,

NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"anyDateField"  ascending:YES];

NSMutableArray *arr = [[array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]]mutableCopy];

Comments

0

You can achieve this like this,

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:FALSE];

[self.Array sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.