2011-08-17 22 views
5

Possiedo un NSMutableArray che contiene 2 tipi di oggetti.Ordina NSmutableArray che contiene 2 tipi di oggetto?

Entrambi gli oggetti contengono un campo per le date (stringhe di data con formati diversi) con nomi diversi.

Qual è il modo migliore e più veloce per ordinarli tutti in base alla data? È possibile utilizzare uno NSSortDescriptor in questa situazione?

risposta

4

Se si prendono di mira Mac OS X v10.6 o iOS4 e superiori si possono ordinare utilizzando comparatore simile a questo

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

Oltre a verificare per la classe che si potrebbe anche verificare se risponde al selettore.

+2

Casting gli oggetti dal 'id' è abbastanza inutile. – Chuck

+0

Sì, ci sono diversi metodi "sortUsing ..." su NSArray, e ognuno di loro dovrebbe fare il lavoro. –

+0

BTW - non è necessario eseguire 'isKindOfClass:' o 'respondsToSelector:' se si utilizzano le categorie .. – nielsbot

1

È possibile aggiungere una categoria per unificare il nome del campo data. Diciamo che le istanze di classe di un avere un campo "dateString" e le istanze della classe di B hanno un campo "creationDateString" ... Si potrebbe fare questo:

@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 

Ora è possibile ordinare tutti gli oggetti nel vostro array loro proprietà sortDate:

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

EDIT O con un descrittore di sorta:

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

si potrebbe anche creare l'archiviazione per-instance per la nuova proprietà 'sortDate', quindi è necessario ricalcolarla solo con la stringa sottostante i cambiamenti. – nielsbot

Problemi correlati