2010-05-17 15 views
34

Ho una matrice di oggetti e ho bisogno di ordinarli in base al loro tasto "titolo". Al momento funziona, anche se utilizza un ordinamento ASCII invece di un tipo naturale. I titoli sono i nomi dei file, in modo da apparire come questo:Come fare un ordinamento naturale su un NSArray?

file1
file2
file3
...
file10
file11
file12

sto ottenendo, come ci si aspetterebbe:

file1
file10
file11
file12
file2
file3
...

Qualcuno sa se c'è un modo integrato per la funzionalità di ordinamento NSArray per ottenere questo ordinamento naturale in contrasto con l'ordinamento alfabetico? Ho trovato alcuni algoritmi generici, ma speravo in qualcosa di built-in ...

+0

http://stackoverflow.com/a/9509181/1224741 – QED

risposta

51

NSString s può essere compared utilizzando l'opzione di confronto NSNumericSearch.

una versione:

NSInteger sort(Obj* a, Obj* b, void*) { 
    return [[a title] compare:[b title] options:NSNumericSearch]; 
} 

result = [array sortedArrayUsingFunction:&sort context:nil]; 

o un po 'più generico:

NSInteger sort(id a, id b, void* p) { 
    return [[a valueForKey:(NSString*)p] 
      compare:[b valueForKey:(NSString*)p] 
      options:NSNumericSearch]; 
} 

result = [array sortedArrayUsingFunction:&sort context:@"title"] 

o utilizzando blocchi:

result = [array sortedArrayUsingComparator:^(Obj* a, Obj* b) { 
    return [[a title] compare:[b title] options:NSNumericSearch]; 
}]; 
+2

proprio quello che stavo cercando! –

+0

impressionante, risparmiare un sacco di tempo – gbk

0

Questo funziona su iOS

NSString *name0 = @"winter"; 
NSString *name1 = @"summer"; 
CFComparisonResult result = CFStringCompareWithOptions(
    (CFStringRef) name0, 
    (CFStringRef) name1, 
    CFRangeMake (0, CFStringGetLength((CFStringRef) name0)), 
    kCFCompareCaseInsensitive | kCFCompareLocalized | kCFCompareNumerically 
); 
4

Sulla base di @ PeterHosey risposta, se si sta lavorando con un array di oggetti stringa:

BREVE RISPOSTA:

NSArray *orderedTitles = [unorderedTitles sortedArrayUsingSelector:@selector(localizedStandardCompare:)]; 

ESEMPIO COMPLETO:

NSArray *unorderedTitles = @[ 
    @"file12", 
    @"file1", 
    @"file10", 
    @"file3", 
    @"file2", 
    @"file11" 
]; 

NSArray *orderedTitles = [unorderedTitles sortedArrayUsingSelector:@selector(localizedStandardCompare:)]; 
NSLog(@"orderedTitles = %@", orderedTitles); 
/* 
orderedTitles = (
    file1, 
    file2, 
    file3, 
    file10, 
    file11, 
    file12 
) 
*/ 
0

si può anche fare l'ordinamento nel modo seguente:

NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"title" ascending:YES selector:@selector(localizedStandardCompare:)]; 
NSArray *sortedItems = [unsortedItems sortedArrayUsingDescriptors:@[sortDescriptor]]; 
Problemi correlati