2010-05-17 7 views
34

Tengo una serie de objetos, y los necesito ordenados por su clave de "título". Actualmente está funcionando, aunque está utilizando un ordenamiento ASCII en lugar de uno natural. Los títulos son los nombres de archivo, por lo que este aspecto:¿Cómo hacer un tipo natural en un NSArray?

archivo1 archivo2

archivo3
...
file10
file11
file12

que estoy recibiendo, como era de esperar:

fichero1
file10
file11
file12
fichero2
archivo3
...

¿Alguien sabe si hay incorporados de una manera a la funcionalidad de clasificación NSArray para obtener esta clasificación natural, a diferencia de la clasificación alfabética? Encontré algunos algoritmos genéricos, pero esperaba algo incorporado ...

+0

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

Respuesta

51

NSString s pueden ser compared usando la opción de comparación NSNumericSearch.

una versión:

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

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

O un poco más genérica:

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 usando bloques:

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

Justo lo que estaba buscando! –

+0

impresionante, ahorre mucho tiempo – gbk

0

Esto funciona en iOS

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

Sobre la base de la respuesta de @ PeterHosey, si está trabajando con una serie de objetos de cadena:

Respuesta corta:

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

EJEMPLO 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

También se puede realizar la ordenación de la siguiente manera:

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