objective c - Ordenar NSArray de cadenas de fechas u objetos
objective-c cocoa (9)
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).
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
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 compare: 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.
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.
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
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.
Una vez que tiene un NSDate
, puede crear un NSSortDescriptor
con initWithKey:ascending:
y luego usar sortedArrayUsingDescriptors:
para hacer la ordenación.
Swift 3.0
myMutableArray = myMutableArray.sorted(by: { $0.date.compare($1.date) == ComparisonResult.orderedAscending })