Сортировка NSArray строк или объектов даты
У меня есть NSArray
, который содержит строки строк (т.е. NSString) следующим образом: "Чт, 21 мая 09 19:10:09 -0700"
Мне нужно отсортировать NSArray
по дате. Я думал о преобразовании строки даты в объект NSDate
сначала, но застрял там, как сортировать объект NSDate
.
Спасибо.
Ответы
Ответ 1
Сохраните даты как объекты NSDate
в NS (Mutable) Array, затем используйте -[NSArray sortedArrayUsingSelector:
или -[NSMutableArray sortUsingSelector:]
и передайте @selector(compare:)
в качестве параметра. Метод -[NSDate compare:]
упорядочит даты в порядке возрастания. Это проще, чем создание NSSortDescriptor
, и намного проще, чем написание собственной функции сравнения. (Объекты NSDate
знают, как сравнивать себя друг с другом, по крайней мере, настолько эффективно, насколько мы могли бы надеяться достичь с помощью пользовательского кода.)
Ответ 2
Если у меня есть NSMutableArray
объектов с полем "beginDate" типа NSDate
, я использую NSSortDescriptor
, как показано ниже:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
Ответ 3
Вы также можете использовать что-то вроде следующего:
//Sort the array of items by date
[self.items sortUsingComparator:^NSComparisonResult(id obj1, id obj2){
return [obj2.date compare:obj1.date];
}];
Но это предполагает, что дата сохраняется как NSDate
, а не NString
, что не должно быть проблемой для make/do. Предпочтительно, я рекомендую также хранить данные в нем в необработанном формате. Легче манипулировать в таких ситуациях.
Ответ 4
Вы можете использовать блоки для сортировки на месте:
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
Ответ 5
Вы можете использовать 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:
взамен.
Ответ 6
В моем случае это сработало:
NSArray *aUnsorted = [dataToDb allKeys];
NSArray *arrKeys = [aUnsorted sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"dd-MM-yyyy"];
NSDate *d1 = [df dateFromString:(NSString*) obj1];
NSDate *d2 = [df dateFromString:(NSString*) obj2];
return [d1 compare: d2];
}];
У меня был словарь, где все ключи, где даты в формате dd-MM-yyyy. И allKeys возвращает ключи словаря несортированными, и я хотел представить данные в хронологическом порядке.
Ответ 7
Как только у вас есть NSDate
, вы можете создать NSSortDescriptor
с помощью initWithKey:ascending:
, а затем использовать sortedArrayUsingDescriptors:
для сортировки.
Ответ 8
Измените это
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
всегда
Ответ 9
Swift 3.0
myMutableArray = myMutableArray.sorted(by: { $0.date.compare($1.date) == ComparisonResult.orderedAscending })