Ordenar NSArray de cadenas de fechas u objetos

Tengo un NSArray que contiene cadenas de fechas (es decir, NSString) como esta: “Jue, 21 de mayo de 09 19:10:09 -0700”

Necesito ordenar el NSArray por fecha. NSDate pensé en convertir la cadena de fecha en un objeto NSDate , pero me quedé atrapado en cómo ordenar por el objeto NSDate .

Gracias.

Almacene las fechas como objetos NSDate en una matriz NS (mutable), luego use -[NSArray sortedArrayUsingSelector: o -[NSMutableArray sortUsingSelector:] y pase @selector(compare:) como el parámetro. El método -[NSDate compare:] ordenará las fechas en orden ascendente para usted. Esto es más simple que crear un NSSortDescriptor , y mucho más simple que escribir su propia función de comparación. ( NSDate objetos NSDate saben cómo compararse entre sí al menos tan eficientemente como podríamos esperar con un código personalizado).

Si tengo un NSMutableArray de objetos con un campo “beginDate” de tipo NSDate , estoy usando un NSSortDescriptor siguiente manera:

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

También puede usar algo como lo siguiente:

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

Pero esto supone que la fecha se almacena como un NSDate lugar de un NString , que no debería ser un problema para hacer / hacer. Preferiblemente, también recomiendo almacenar los datos en su formato sin formato. Facilita la manipulación en situaciones como esta.

Puede usar bloques para clasificar en su lugar:

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

Le sugiero que convierta todas sus cadenas de caracteres a fechas antes de ordenarlas para que no se realicen más conversiones que las fechas. Cualquier algoritmo de clasificación le dará más conversiones de cadena a fecha que el número de elementos en la matriz (a veces sustancialmente más)

un poco más sobre la clasificación de bloques: http://sokol8.blogspot.com/2011/04/sorting-nsarray-with-blocks.html

Puede usar sortedArrayUsingFunction:context: Aquí hay una muestra:

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

Al usar un NSMutableArray , puede usar sortArrayUsingFunction:context: lugar.

Una vez que tiene un NSDate , puede crear un NSSortDescriptor con initWithKey:ascending: y luego usar sortedArrayUsingDescriptors: para hacer la ordenación.

Lo que funcionó en mi caso fue el siguiente:

  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 comparar: d2];
     }]; 

Tenía un diccionario, donde todas las teclas tenían fechas en formato dd-MM-aaaa. Y allKeys devuelve las claves del diccionario sin clasificar, y quería presentar los datos en orden cronológico.

Cambia esto

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

A

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

Solo cambia la LLAVE: debe ser siempre la Date

Swift 3.0

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