web-dev-qa-db-fra.com

Tri des valeurs NSString comme si NSInteger en utilisant NSSortDescriptor

J'ai créé un descripteur de tri pour trier une réponse plist provenant de mon serveur. Cela fonctionne bien avec une clé de tri ayant des valeurs allant jusqu'à 9. Avec plus de 10 éléments, je vois des résultats abrupts avec une clé de tri agencée dans l'ordre = 1, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9.

NSSortDescriptor *aSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sort" ascending:YES];
self.myList = [NSMutableArray arrayWithArray:[unsortedList sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]]];

Comment faire pour organiser dans le bon ordre de 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11?

28
Abhinav

Pour ce faire, vous pouvez implémenter un bloc de comparaison personnalisé lors de la création de votre NSSortDescriptor:

NSSortDescriptor *aSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"sort" ascending:YES comparator:^(id obj1, id obj2) {

    if ([obj1 integerValue] > [obj2 integerValue]) {
        return (NSComparisonResult)NSOrderedDescending;
    }
    if ([obj1 integerValue] < [obj2 integerValue]) {
        return (NSComparisonResult)NSOrderedAscending;
    }
    return (NSComparisonResult)NSOrderedSame;
}];
self.myList = [NSMutableArray arrayWithArray:[unsortedList sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]]];

Voir la documentation Apple ici

44
jonkroll

[list sortUsingSelector:@selector(localizedStandardCompare:)]; va trier la liste de manière "humaine" (donc "11" sera le dernier, pas entre "1" et "2"). Mais si vous voulez vraiment traiter ces chaînes comme des nombres, vous devez d'abord les numéroter!

38
Vincent Gable
NSSortDescriptor *aSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sort.intValue" ascending:YES];
self.myList = [NSMutableArray arrayWithArray:[unsortedList sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]]];

Triez en fonction de la valeur de l'entier.

16
lucidbeing

Vous avez besoin que vos chaînes soient comparées avec l'option NSNumericSearch :

NSNumericSearch
Les nombres contenus dans des chaînes sont comparés à l'aide d'une valeur numérique, c'est-à-dire Name2.txt <Name7.txt <Name25.txt.

qui nécessite que la méthode compare:options: soit appelée pour la comparaison.

Pour ce faire, votre descripteur de tri peut utiliser un bloc NSComparator Block :

[NSSortDescriptor sortDescriptorWithKey:@"self"
                              ascending:YES
                             comparator:^(NSString * string1, NSString * string2){
                                            return [string1 compare:string2
                                                            options:NSNumericSearch];
 }];

Ou bien, vous pouvez ignorer le descripteur de tri et simplement trier le tableau directement , en utilisant le même bloc:

[unsortedList sortedArrayUsingComparator:^NSComparisonResult (NSString * string1, NSString * string2){
    return [string1 compare:string2
                    options:NSNumericSearch];
 }];
11
Josh Caswell
NSMutableArray *list = [NSMutableArray arrayWithObjects:@"11",@"2",@"3",@"1", nil];
[list sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    NSInteger firstInteger = [obj1 integerValue];
    NSInteger secondInteger = [obj2 integerValue];
    if( firstInteger > secondInteger) return NSOrderedDescending;
    if( firstInteger == secondInteger) return NSOrderedSame;
    return NSOrderedAscending; // edited
}];

Aucune garantie de performance

7
FluffulousChimp

Toutes les méthodes ci-dessus nécessitent une bonne connaissance des bases à mettre en œuvre; mais pour les débutants, je suggère le moyen le plus simple - d'utiliser la méthode du bloc natif

NSArray* sortedArr =[fetchResults sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {

    int aValue = [[a valueForKey:@"subgroupId"] intValue];
    int bValue = [[b valueForKey:@"subgroupId"] intValue];

    return aValue > bValue;
}];
0
Subash V

contribution

{
    "seats": [{
        "seatNumber": "1"
    }, {
        "seatNumber": "10"
    }, {
        "seatNumber": "2"
    }]
}

triez à l'aide de [NSSortDescriptor sortDescriptorWithKey: @ "seatNumber" croissant: OUI sélecteur: @selector (localizedStandardCompare :)]]. La clé est d'utiliser localizedStandardCompare. Cela vous résoudra le problème.

NSArray *seats = [self.seats sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"seatNumber" ascending:YES selector:@selector(localizedStandardCompare:)]]];

sortie

{
    "seats": [{
        "seatNumber": "1"
    }, {
        "seatNumber": "2"
    }, {
        "seatNumber": "10"
    }]
}

documentation: https://developer.Apple.com/documentation/foundation/nsstring/1409742-localizedstandardcompare

0
starfall