2009-07-15 5 views
81

Ich habe ein NSArray die Datumsstrings (dh NSString) wie folgt enthält: „Do 21 9. Mai 19.10.09 -0700“Sortieren NSArray von Datumszeichenketten oder Objekte

Ich brauche die sortieren NSArray nach Datum. Ich dachte über das Umwandeln der Datumszeichenkette zuerst in ein NSDate Objekt nach, aber steckte dort fest, wie man durch das NSDate Objekt sortiert.

Danke.

+0

da diese Retagged an die Stiftung Rahmen verwandt und nicht spezifisch für das iPhone. –

Antwort

108

Shop die Daten als NSDate Objekte in einem NS (Mutable) Array, verwenden Sie dann -[NSArray sortedArrayUsingSelector: oder -[NSMutableArray sortUsingSelector:] und @selector(compare:) als Parameter übergeben. Die -[NSDate compare:] Methode wird Daten in aufsteigender Reihenfolge für Sie bestellen. Dies ist einfacher als das Erstellen einer NSSortDescriptor und viel einfacher als das Schreiben einer eigenen Vergleichsfunktion. (NSDate Objekte wissen, wie sie sich zumindest so effizient miteinander zu vergleichen, wie wir mit benutzerdefinierten Code zu erreichen hoffen konnte.)

+11

Es ist nicht klar, ob die ursprüngliche Frage zum Sortieren eines Datumsbereichs oder zum Sortieren eines Arrays von Objekten mit einem Datumsfeld erforderlich war. Dies ist der einfachste Ansatz, wenn es der erste ist, aber wenn es der letztere ist, ist NSSortDescriptor der Weg zu gehen. – smorgan

+0

@smorgan Wie behandelt NSSortDescriptor keine Daten? – Ash

+0

Vielen Dank für Ihre Hilfe, ich denke, wir sollten mehr in Apple Docs lesen, aber es scheint so langweilig, bis Sie es verwenden. – Abo3atef

4

Sobald Sie eine NSDate haben, können Sie eine NSSortDescriptor mit initWithKey:ascending: erstellen und dann sortedArrayUsingDescriptors: verwenden, um die Sortierung zu tun.

+0

Dieser Ansatz funktioniert, aber die Verwendung von -sortedArrayUsingSelector: ist etwas einfacher und erfordert kein zusätzliches Objekt. –

+0

Pre-Editing, die Frage erwähnt "ein 'Datum' Schlüssel", so nahm ich an, dies war wirklich ein Array von Objekten/Wörterbücher, die ein Datum als ein Feld hatte, nicht ein Array von rohen Daten. In diesem Fall ist sortedArrayUsingSelector: komplexer, da für das Suchen eine benutzerdefinierte Sortierroutine geschrieben werden muss. – smorgan

+0

Ja, tut mir Leid wegen irgendwelcher Verwirrung - ich habe diesen Verweis gelöscht, da er gerade gesagt hat, dass er sein Array mit einem 'Datum'-Schlüssel speichert, und mir wurde klar, dass es die Frage nur verwirrender machte. Sie haben definitiv Recht bezüglich der relativen Komplexität bei einer komplexeren Datenstruktur. –

5

Sie können sortedArrayUsingFunction:context: verwenden. Hier ist ein Beispiel:

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

Wenn ein NSMutableArray verwenden, können Sie sortArrayUsingFunction:context: stattdessen verwenden.

+8

Das ist eine schlechte Idee - eine Vergleichsfunktion sollte schnell sein und NSDate-Objekte nicht aus Strings für jeden Vergleich erstellen müssen. Wenn Sie bereits - [NSDate vergleichen:] verwenden, speichern Sie einfach die Daten im Array und verwenden Sie -sortedArrayUsingSelector: direkt. –

+0

Ich denke, das ist eine gute Lösung, wenn Sie Objekte sortieren, die bereits ein NSDate-Feld haben. Nein? – GnarlyDog

+1

Wenn das Array bereits 'NSDate' Objekte enthält, können Sie meine Antwort oben verwenden, oder verwenden Sie sogar' - [NSMutableArray sortUsingComparator:] ', die in 10.6 hinzugefügt wurde. –

111

Wenn ich eine NSMutableArray von Objekten mit einem Feld „Begindate“ vom Typ NSDate ich verwende ein NSSortDescriptor wie folgt:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE]; 
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
[sortDescriptor release]; 
+3

Ich weiß, dass viel Zeit vergangen ist (als die vorherige Antwort akzeptiert wurde, könnte es noch keinen NSSortDescriptor geben), aber für die zukünftige Verwendung sollte diese die richtige Antwort sein. – Vive

+1

denke auch so;) – vinzenzweber

+1

Dies ist eine wunderbare Lösung. löste mein Problem in ein paar Zeilen Code.Thanx eine Tonne @vinzenzweber –

9

Sie Blöcke können an Ort und Stelle sortieren:

sortedDatesArray = [[unsortedDatesArray sortedArrayUsingComparator: ^(id a, id b) { 
    NSDate *d1 = [NSDate dateWithString: s1]; 
    NSDate *d2 = [NSDate dateWithString: s2]; 
    return [d1 compare: d2]; 
}]; 

ich schlage vor, Sie alle Ihre Strings Daten konvertieren, bevor nicht die Sortierung der Umwandlung m zu tun Zeiten, als es Datumsangaben gibt. Jede Sortieralgorithmus wird Ihnen mehr Zeichenfolge bisher Conversions als die Anzahl der Elemente im Array (manchmal wesentlich mehr)

ein bisschen mehr auf Blöcke Sortierung: http://sokol8.blogspot.com/2011/04/sorting-nsarray-with-blocks.html

+0

Dies ist eine Variante der gleichen suboptimalen Idee, die von @notoop präsentiert wird. In jedem Fall ist die Konvertierung nach NSDate der richtige Weg. –

+1

Was ist die optimale Idee? –

+0

Er im Grunde nur meine Antwort mit @ Nooop's Antwort ..... ziemlich unnötig, diese zu verdoppeln, wenn Sie mich fragen .... – TheCodingArt

16

Sie auch so etwas wie die folgenden verwenden:

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

Aber dies ist davon ausgehen, dass das Datum als NSDate gespeichert ist eher ein NString, das sollte kein Problem sein/zu tun zu machen. Vorzugsweise empfehle ich, die Daten auch im Rohformat zu speichern. Erleichtert die Manipulation in Situationen wie diesem.

1

Ändern Sie diese

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:TRUE]; 
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
[sortDescriptor release]; 

Um

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Date" ascending:TRUE]; 
[myMutableArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
[sortDescriptor release]; 

einfach den Schlüssel zu ändern: es Date

immer sein muss
4

Was es in meinem Fall arbeitete, war folgendes:

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

Ich hatte ein Wörterbuch, in dem alle Schlüssel Daten im Format TT-MM-JJJJ hatten. Und allKeys gibt die Wörterbuchschlüssel unsortiert zurück, und ich wollte die Daten in chronologischer Reihenfolge darstellen.

0

Swift 3,0

myMutableArray = myMutableArray.sorted(by: { $0.date.compare($1.date) == ComparisonResult.orderedAscending })