2011-08-17 11 views
5

Tengo un NSMutableArray que contiene 2 tipos de objetos.Ordenar NSmutableArray que contiene 2 tipos de objetos?

Ambos objetos contienen un campo para las fechas (cadenas de fechas con diferentes formatos) con diferentes nombres.

¿Cuál es la mejor y más rápida forma de ordenarlas todas según la fecha? ¿Es posible usar un NSSortDescriptor en esta situación?

Respuesta

4

Si el idioma de Mac OS X v10.6 o iOS4 y superior se puede ordenar el uso comparador similar a este

NSDateFormatter *formatter1 = ...; //create and configure date formatter for Class1 
NSDateFormatter *formatter2 = ...; //create and configure date formatter for Class2 


[arrayOfObjects sortUsingComparator:^NSComparisonResult(id obj1, id obj2) { 
    NSDate *date1 = nil, *date2 = nil; 
    //Get first objects date 
    if([obj1 isKindOfClass:[Class1 class]]) 
    { 
     date1 = [formatter1 dateFromString:[obj1 class1Date]]; 
    } 
    else if([obj1 isKindOfClass:[Class2 class]]) 
    { 
     date1 = [formatter2 dateFromString:[obj1 class2Date]]; 
    } 

    //Get second objects date 
    if([obj2 isKindOfClass:[Class1 class]]) 
    { 
     date2 = [formatter1 dateFromString:[obj2 class1Date]]; 
    } 
    else if([obj2 isKindOfClass:[Class2 class]]) 
    { 
     date2 = [formatter2 dateFromString:[obj2 class2Date]]; 
    } 

    NSAssert(date1 != nil, @"Could not parse date from %@", obj1); 
    NSAssert(date2 != nil, @"Could not parse date from %@", obj2); 

    return [date1 compare:date2]; 
}]; 

Además de la comprobación de la clase también se puede comprobar si responde al selector.

+2

reparto de los objetos 'id' es totalmente innecesario. – Chuck

+0

Sí, hay varios métodos de "ordenamiento ..." en NSArray, y cualquiera de ellos debería hacer el trabajo. –

+0

BTW - no es necesario ejecutar 'isKindOfClass:' o 'respondsToSelector:' si utiliza categorías ... – nielsbot

1

Puede agregar una categoría para unificar el nombre del campo de fecha. Digamos que las instancias de clase de un tener un campo "DateString" y las instancias de clase de B tienen un campo "creationDateString" ... Usted puede hacer esto:

@implementation A (SortByDate) 

-(NSDate*)sortDate 
{ 
    static NSDateFormatter * formatter = nil ; 
    static dispatch_once_t once = 0 ; 
    dispatch_once(& once, ^{ formatter = ... }) ; 

    return [ formatter dateFromString:self.dateString ] ; 
} 
@end 

@implementation B (SortByDate) 
-(NSDate*)sortDate 
{ 
    static NSDateFormatter * formatter = nil ; 
    static dispatch_once_t once = 0 ; 
    dispatch_once(& once, ^{ formatter = ... }) ; 

    return [ formatter dateFromString:self.creationDateString ] ; 
} 
@end 

Ahora usted puede ordenar todos los objetos de la matriz por sus propiedades sortDate:

NSArray * sortedByDateArray = [ unsortedArray sortedArrayUsingComparator:^(id a, id b){ 
    return [ [ a sortDate ] compare:[ b sortDate ] ] ; 
}]; 

EDITAR o con un descriptor para ordenar:

NSArray * sortedArray = [ unsortedArray sortedArrayUsingDescriptors:[ NSArray arrayWithObject:[ NSSortDescriptor sortDescriptorWithKey:@"sortDate" ascending:YES ] ] ] ; 
+0

incluso podría crear almacenamiento por instancia para su nueva propiedad 'sortDate' por lo que solo necesita volver a calcularse con la cadena subyacente cambios. – nielsbot

Cuestiones relacionadas