Сортировать NSArray из строк или объектов даты
У меня есть NSArray
который содержит строки даты (т.е. NSString), например: "Чт, 21 мая 09 19:10:09 -0700"
Мне нужно отсортировать NSArray
по дате Я думал о преобразовании строки даты в NSDate
объект, но застрял там о том, как сортировать по NSDate
объект.
Благодарю.
9 ответов
Храните даты как NSDate
объекты в NS(Mutable)Array, затем используйте -[NSArray sortedArrayUsingSelector:
или же -[NSMutableArray sortUsingSelector:]
и передать @selector(compare:)
в качестве параметра. -[NSDate compare:]
Метод упорядочит даты в порядке возрастания для вас. Это проще, чем создать NSSortDescriptor
и гораздо проще, чем написать собственную функцию сравнения. (NSDate
объекты знают, как сравнивать себя друг с другом, по крайней мере, настолько эффективно, насколько мы могли бы надеяться достичь с помощью пользовательского кода.)
Если у меня есть NSMutableArray
объектов с полем "beginDate" типа NSDate
Я использую NSSortDescriptor
как показано ниже:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
Вы также можете использовать что-то вроде следующего:
//Sort the array of items by date
[self.items sortUsingComparator:^NSComparisonResult(id obj1, id obj2){
return [obj2.date compare:obj1.date];
}];
Но это предполагает, что дата хранится как NSDate
скорее NString
, что не должно быть проблемой, чтобы сделать / сделать. Желательно также рекомендовать хранить данные в необработанном формате. Облегчает манипулирование в таких ситуациях.
Вы можете использовать блоки для сортировки на месте:
sortedDatesArray = [[unsortedDatesArray sortedArrayUsingComparator: ^(id a, id b) {
NSDate *d1 = [NSDate dateWithString: s1];
NSDate *d2 = [NSDate dateWithString: s2];
return [d1 compare: d2];
}];
Я советую вам конвертировать все ваши строки в даты перед сортировкой, чтобы не выполнять преобразование чаще, чем есть элементы даты. Любой алгоритм сортировки даст вам больше преобразований строки в дату, чем количество элементов в массиве (иногда существенно больше)
немного больше о сортировке блоков: http://sokol8.blogspot.com/2011/04/sorting-nsarray-with-blocks.html
В моем случае это сработало:
NSArray * aUnsorted = [dataToDb allKeys]; NSArray * arrKeys = [aUnsorted sortedArrayUsingComparator: ^ NSComparisonResult (идентификатор obj1, идентификатор obj2) { NSDateFormatter *df = [[NSDateFormatter alloc] init]; [df setDateFormat:@"dd-MM-yyyy"]; NSDate *d1 = [df dateFromString:(NSString*) obj1]; NSDate *d2 = [df dateFromString:(NSString*) obj2]; возврат [d1 сравнить: d2]; }];
У меня был словарь, где все ключи, где даты в формате дд-мм-гггг. И allKeys возвращает ключи словаря не отсортированными, и я хотел представить данные в хронологическом порядке.
Ты можешь использовать sortedArrayUsingFunction:context:
, Вот образец:
NSComparisonResult dateSort(NSString *s1, NSString *s2, void *context) {
NSDate *d1 = [NSDate dateWithString:s1];
NSDate *d2 = [NSDate dateWithString:s2];
return [d1 compare:d2];
}
NSArray *sorted = [unsorted sortedArrayUsingFunction:dateSort context:nil];
При использовании NSMutableArray
, ты можешь использовать sortArrayUsingFunction:context:
вместо.
Когда у вас есть NSDate
Вы можете создать NSSortDescriptor
с initWithKey:ascending:
а затем использовать sortedArrayUsingDescriptors:
сделать сортировку.
Swift 3.0
myMutableArray = myMutableArray.sorted(by: { $0.date.compare($1.date) == ComparisonResult.orderedAscending })
Изменить это
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
к
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Date" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
Просто измените КЛЮЧ: это должно быть Date
всегда