Сортировать NSArray пользовательских объектов по их свойствам NSDate - PullRequest
15 голосов
/ 21 мая 2011

Я пытаюсь отсортировать NSArray, заполненный пользовательскими объектами. Каждый объект имеет свойство startDateTime, которое имеет тип NSDate.

Следующий код приводит к массиву sortedEventArray, заполненному, но не отсортированному. Я иду по этому совершенно неправильному пути или я просто пропускаю что-то маленькое?

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

Ответы [ 5 ]

25 голосов
/ 22 мая 2011

Вы уверены, что переменные экземпляра startDateTime событий узла не равны нулю?

Если у вас его еще нет, вы можете добавить (пользовательский) метод -description к объектам событий вашего узла, который делает что-то вроде этого:

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

Затем в вашей сортировкеЗаписать в журнал массив до и после:

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

Если startDateTime все nil, то массивы до и после будут иметь одинаковый порядок (поскольку операция сортировки приравнивается к отправкевсе сообщения -compare: на nil, что в принципе ничего не делает).

11 голосов
/ 05 октября 2012

Хорошо, я знаю, что это немного поздно, но вот как бы я это сделал:

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

Очевидно, замените Event классом вашего пользовательского объекта. Преимущество этого подхода в том, что вы защищены от будущего рефакторинга. Если бы вам пришлось провести рефакторинг и переименовать свойство startDateTime во что-то другое, Xcode, вероятно, не изменил бы строку, которую вы передаете в дескриптор сортировки. Внезапно ваш код сортировки сломается / ничего не сделает.

11 голосов
/ 21 мая 2011

Вы пытались указать компаратор NSDate?

Например:

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

Это должно обеспечить использование правильного компаратора класса NSDate.

0 голосов
/ 01 января 2014

Вы можете достичь, как это,

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

NSMutableArray *arr = [[array sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]]mutableCopy];
0 голосов
/ 22 июля 2013

Вы можете достичь этого, как это,

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

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