Сортировать NSArray из строк или объектов даты

у меня естьNSArray который содержит строки даты(i.e. NSString) вот так: "Четверг, 21 мая 09 19:10:09 -0700"

Мне нужно отсортироватьNSArray по дате Я думал о преобразовании строки даты вNSDate объект, но застрял там о том, как сортировать поNSDate объект.

Благодарю.

 Quinn Taylor15 июл. 2009 г., 23:26
Повторно помечен, поскольку это связано с платформой Foundation, а не только с iPhone.

Ответы на вопрос(9)

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 всегда

NSDateВы можете создатьNSSortDescriptor сinitWithKey:ascending: а затем использоватьsortedArrayUsingDescriptors: сделать сортировку.

 16 июл. 2009 г., 05:44
Предварительное редактирование, упомянутый вопрос «дата» ключ & quot ;, поэтому я предположил, что это действительно массив объектов / словарей, в которых дата была одним полем, а не массив необработанных дат. В этом случае sortedArrayUsingSelector: является более сложным, поскольку для поиска требуется написать собственную процедуру сортировки.
 15 июл. 2009 г., 23:28
Этот подход будет работать, но использование -sortedArrayUsingSelector: немного проще и не требует создания дополнительного объекта.
 16 июл. 2009 г., 06:24
Да, извините за путаницу & # x2014; Я удалил эту ссылку, так как он просто говорил, что хранит свой массив с «датой». ключ, и я понял, что это только сделало вопрос более запутанным. Вы определенно правы относительно относительной сложности, учитывая более сложную структуру данных.

//Sort the array of items by  date
    [self.items sortUsingComparator:^NSComparisonResult(id obj1, id obj2){
        return [obj2.date compare:obj1.date];
    }];

But this does assume that the date is stored as a NSDate rather a NString, который должен быть без проблем, чтобы сделать / сделать. Предпочтительно я рекомендую также хранить данные в необработанном формате. Облегчает манипулирование в таких ситуациях.

NSMutableArray объектов с полем «beginDate» типаNSDate Я используюNSSortDescriptor как показано ниже:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
 27 авг. 2012 г., 17:05
Я знаю, что прошло много времени (когда был принят предыдущий ответ, еще не могло быть NSSortDescriptor), но для будущего использования этот ответ должен быть правильным.
 27 сент. 2012 г., 09:08
Это потрясающее решение. решил мою проблему в несколько строк кода. Спасибо за тонну @vinzenzweber
 28 авг. 2012 г., 10:47
тоже так думаю Smile
 20 окт. 2012 г., 00:12
На самом деле ... Я был в шоке, это сработало при первом запуске! Я думал, что initWithKey был зарезервирован для словарей, где определен ключ, но все, что вам нужно сделать, это ссылаться на свойство в массиве объектов? Пусть светит винзенцвеберскавичски свет !!
 02 нояб. 2012 г., 00:32
NSSortDescriptor существует с OS X 10.3 в конце 2003 года. Это немного другой сценарий, где дата - это поле в другом объекте. С еще более современным API вы можете использовать-[NSMutableArray sortUsingComparator:] (10.6+) и передать блок, который возвращает результат вызова-compare: на двух полях. Это, вероятно, будет быстрее, чем звонить-valueForKey: на каждом объекте. Вы могли бы даже использовать-sortWithOptions:usingComparator: и передавать параметры для сортировки одновременно.

Вы можете использовать блоки для сортировки на месте:

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

 28 янв. 2012 г., 10:12
какая оптимальная идея?
 09 сент. 2014 г., 08:23
Это намного медленнее, чем анализ строк даты в массив NSDate, а затем сортировка массива NSDate, потому что будет 2 * (n - 1) раз дополнительный разбор строки. Разбор строк, как правило, тяжелая работа на процессоре.
 23 янв. 2012 г., 09:17
Это вариант той же самой неоптимальной идеи, представленной @notoop. В любом случае, сначала нужно перейти на NSDate.
 26 мар. 2013 г., 16:15
Он просто поместил мой ответ с ответом @ notoop's ... совершенно не нужно дважды публиковать их, если вы спросите меня ....

Swift 3.0

 { $0.date.compare($1.date) == ComparisonResult.orderedAscending })

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: вместо.

 02 нояб. 2012 г., 00:35
Если массив уже содержитNSDate объекты, вы можете использовать мой ответ выше, или даже использовать-[NSMutableArray sortUsingComparator:], который был добавлен в 10.6.
 10 июл. 2015 г., 19:34
Если вы используете массив словаря, в котором есть объект значения ключа для даты как NSString вместе с некоторыми другими объектами значения ключа, то это решение пока лучшее. Просто нужно немного изменить внутри функции dateSort. Пальцы вверх! :)
 15 июл. 2009 г., 23:14
Это плохая идея & # x2014; функция сравнения должна быть быстрой и не должна создавать объекты NSDate из строк для каждого сравнения. Если вы уже используете - [NSDate сравнить:], просто сохраните даты в массиве и используйте -sortedArrayUsingSelector: напрямую.
 29 авг. 2012 г., 00:12
Я думаю, что это хорошее решение, если вы сортируете объекты, которые уже имеют поле NSDate. Нет?
Решение Вопроса

NSDate объекты в NS (Mutable) Array, затем используйте-[NSArray sortedArrayUsingSelector: или же-[NSMutableArray sortUsingSelector:] и передать@selector(compare:) в качестве параметра.-[NSDate compare:] Метод упорядочит даты в порядке возрастания для вас. Это проще, чем создатьNSSortDescriptorи гораздо проще, чем написать собственную функцию сравнения. (NSDate объекты знают, как сравнивать себя друг с другом, по крайней мере, настолько эффективно, насколько мы могли бы надеяться достичь с помощью пользовательского кода.)

 29 авг. 2014 г., 08:42
Не могли бы вы показать это в фрагменте кода в качестве примера? Заранее спасибо.
 25 нояб. 2013 г., 23:35
@smorgan, как NSSortDescriptor обрабатывает ноль дат?
 16 июл. 2009 г., 05:48
Непонятно, задавался ли первоначальный вопрос о сортировке массива дат или массиве объектов, имеющих поле даты. Это самый простой подход, если он первый, но если второй, то NSSortDescriptor - это путь.
 22 дек. 2013 г., 18:28
Спасибо за вашу помощь, я думаю, что мы должны читать больше в Apple Docs, но это кажется таким скучным, пока вы его не используете.

    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];
    }];

У меня был словарь, где все ключи, где даты в формате дд-мм-гггг. И allKeys возвращает ключи словаря не отсортированными, и я хотел представить данные в хронологическом порядке.

Ваш ответ на вопрос