37 votes

Comment faire un tri naturel sur un NSArray ?

J'ai un tableau d'objets et j'ai besoin qu'ils soient triés par leur clé "title". Cela fonctionne actuellement, mais en utilisant un tri ASCII au lieu d'un tri naturel. Les titres sont des noms de fichiers, donc ils ressemblent à ceci :

fichier 1
fichier2
fichier3
...
dossier10
fichier 11
fichier 12

J'y arrive, comme vous pouvez vous y attendre :

fichier 1
dossier10
fichier 11
fichier 12
fichier2
fichier3
...

Quelqu'un sait-il s'il existe un moyen intégré à la fonctionnalité de tri de NSArray pour obtenir ce tri naturel par opposition au tri alphabétique ? J'ai trouvé quelques algorithmes génériques, mais j'espérais quelque chose d'intégré.

0 votes

54voto

Georg Fritzsche Points 59185

NSString peuvent être comparé à en utilisant le NSNumericSearch comparer l'option.

Une version :

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

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

Ou un peu plus générique :

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"]

Ou en utilisant des blocs :

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

25voto

Peter Hosey Points 66275

Ceux qui tentent de reproduire le comportement de tri du Finder sur Mac OS X 10.6 et ultérieur et iOS 4 et ultérieur peuvent utiliser localizedStandardCompare: comme sélecteur de comparateur.

Ceux qui ont le même objectif sur des versions antérieures de Mac OS X et/ou iOS doivent utiliser la solution décrite dans le Guide de programmation des chaînes de caractères .

0 votes

Tous les liens sont cassés.

4voto

John Erck Points 1614

En se basant sur la réponse de @PeterHosey, si vous travaillez avec un tableau d'objets de type chaîne :

RÉPONSE COURTE :

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

EXEMPLE COMPLET :

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

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

0voto

gypsicoder Points 2306

Vous pouvez également effectuer le tri de la manière suivante :

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

0voto

neoneye Points 11545

Cela fonctionne sur iOS

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X