Сортировать NSArray из строк или объектов даты - PullRequest
82 голосов
/ 15 июля 2009

У меня есть NSArray, который содержит строки даты (т. Е. Строка NSString) , например: "Чт, 21 мая 09 19:10:09 -0700"

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

Спасибо.

Ответы [ 9 ]

113 голосов
/ 12 октября 2010

Если у меня есть NSMutableArray объектов с полем "beginDate" типа NSDate, я использую NSSortDescriptor, как показано ниже:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE];
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
109 голосов
/ 16 июля 2009

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

16 голосов
/ 10 ноября 2012

Вы также можете использовать что-то вроде следующего:

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

Но это предполагает, что дата хранится как NSDate, а не NString, что не должно быть проблемой для создания / выполнения. Желательно также рекомендовать хранить данные в необработанном формате. Облегчает манипулирование в таких ситуациях.

9 голосов
/ 14 апреля 2011

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

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 голосов
/ 16 января 2015

В моем случае это сработало:

    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 возвращает ключи словаря не отсортированными, и я хотел представить данные в хронологическом порядке.

5 голосов
/ 15 июля 2009

Вы можете использовать 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:.

4 голосов
/ 15 июля 2009

Получив NSDate, вы можете создать NSSortDescriptor с помощью initWithKey:ascending:, а затем использовать sortedArrayUsingDescriptors: для сортировки.

1 голос
/ 20 сентября 2017

Swift 3.0

myMutableArray = myMutableArray.sorted(by: { $0.date.compare($1.date) == ComparisonResult.orderedAscending })
1 голос
/ 01 мая 2013

Изменить это

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

...