Mam NSArray
ciąg zawierający daty (np. NSString) w następujący sposób: „Thu, 21 May 09 19:10:09 -0700”
Muszę posortować NSArray
według daty. NSDate
Najpierw pomyślałem o przekonwertowaniu ciągu daty na obiekt, ale utknąłem na tym, jak sortować według NSDate
obiektu.
Dzięki.
Odpowiedzi:
Przechowuj daty jako
NSDate
obiekty w tablicy NS (Mutable), a następnie użyj-[NSArray sortedArrayUsingSelector:
lub-[NSMutableArray sortUsingSelector:]
i przekaż@selector(compare:)
jako parametr. Ta-[NSDate compare:]
metoda uporządkuje daty w kolejności rosnącej. Jest to prostsze niż tworzenieNSSortDescriptor
i znacznie prostsze niż pisanie własnej funkcji porównania. (NSDate
obiekty potrafią porównywać się ze sobą co najmniej tak skutecznie, jak moglibyśmy mieć nadzieję, że uda się to osiągnąć za pomocą niestandardowego kodu).źródło
Jeśli mam
NSMutableArray
obiekty z polem „beginDate” typuNSDate
, używamNSSortDescriptor
poniższego:NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE]; [myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; [sortDescriptor release];
źródło
-[NSMutableArray sortUsingComparator:]
(10.6+) i przekazać blok, który zwraca wynik wywołania-compare:
dwóch pól. Prawdopodobnie byłoby to szybsze niż wywołanie-valueForKey:
każdego obiektu. Możesz nawet używać-sortWithOptions:usingComparator:
i przekazywać opcje do sortowania jednocześnie.Możesz także użyć czegoś podobnego do następującego:
//Sort the array of items by date [self.items sortUsingComparator:^NSComparisonResult(id obj1, id obj2){ return [obj2.date compare:obj1.date]; }];
Ale to zakłada, że data jest przechowywana jako
NSDate
raczej aNString
, co nie powinno stanowić problemu. Zalecam również przechowywanie danych w formacie surowym. Ułatwia manipulowanie w takich sytuacjach.źródło
Możesz użyć bloków do sortowania w miejscu:
sortedDatesArray = [[unsortedDatesArray sortedArrayUsingComparator: ^(id a, id b) { NSDate *d1 = [NSDate dateWithString: s1]; NSDate *d2 = [NSDate dateWithString: s2]; return [d1 compare: d2]; }];
Proponuję przekonwertować wszystkie ciągi na daty przed sortowaniem, aby nie wykonywać konwersji więcej razy niż jest to w przypadku elementów daty. Dowolny algorytm sortowania zapewni więcej konwersji ciągów do daty niż liczba elementów w tablicy (czasami znacznie więcej)
trochę więcej o sortowaniu bloków: http://sokol8.blogspot.com/2011/04/sorting-nsarray-with-blocks.html
źródło
W moim przypadku zadziałało:
Miałem słownik, w którym wszystkie klucze miały daty w formacie dd-MM-yyyy. AllKeys zwraca klucze słownika nieposortowane, a ja chciałem przedstawić dane w porządku chronologicznym.
źródło
Możesz użyć
sortedArrayUsingFunction:context:
. Oto próbka: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];
Używając a
NSMutableArray
, możesz użyćsortArrayUsingFunction:context:
zamiast tego.źródło
NSDate
obiekty, możesz skorzystać z mojej odpowiedzi powyżej, a nawet użyć-[NSMutableArray sortUsingComparator:]
, która została dodana w 10.6.Gdy już masz
NSDate
, możesz utworzyćNSSortDescriptor
z,initWithKey:ascending:
a następnie użyćsortedArrayUsingDescriptors:
do sortowania.źródło
Swift 3.0
myMutableArray = myMutableArray.sorted(by: { $0.date.compare($1.date) == ComparisonResult.orderedAscending })
źródło
Zmień to
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE]; [myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; [sortDescriptor release];
Do
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Date" ascending:TRUE]; [myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; [sortDescriptor release];
Po prostu zmień KLUCZ: musi być
Date
zawszeźródło