2011-08-25 4 views
3

J'ai effectué une bonne recherche de SO mais je n'ai trouvé aucun élément pertinent à ce problème. J'ai une classe d'objet personnalisée qui implémente une méthode de comparaison pour le tri dans les tableaux. Cette comparaison utilise la propriété "name" de la classe à l'aide de NSCaseInsensitiveSearch. Le code ressemble à ceci:Tri des chaînes avec les chiffres du dernier objectif c

- (NSComparisonResult)compare:(Forum *)otherObject { 
return [self.name compare:otherObject.name options:(NSCaseInsensitiveSearch)]; 
} 

Cependant, l'utilisation NSCaseInsensitiveSearch met des chaînes avec des chiffres en avance sur les chaînes avec des lettres. Y a-t-il un moyen de faire le contraire de cela afin que les chiffres viennent après les lettres?

Répondre

1

Ne vous contentez pas

return [self.name compare:otherObject.name options:(NSCaseInsensitiveSearch)]; 

Mais faire quelques vérifications supplémentaires, par exemple si self.name commence par un non-numeral et otherObject.name commence par un chiffre, puis retourne NSDescendingOrder, et vice versa. IOW, faites un chiffre> non numérique. Si les deux sont non numéraux ou les deux sont des chiffres, retournez ce que vous avez déjà eu.

Ce petit programme de console explique le principe que je veux dire:

#import <Foundation/Foundation.h> 

int main (int argc, const char * argv[]) 
{ 

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    NSMutableArray *array = [NSMutableArray arrayWithObjects: 
          @"Adam", @"001", @"Bertha", @"3SeriesBMW", @"Colin", 
          @"Zelda", @"1And1", @"Xaver", @"Kraftwerk", @"TangerineDream", 
          @"5SeriesBMW", @"0ableTypes", nil]; 

    NSString *sortOrder = @"AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz_"; 

    [array sortUsingComparator:^NSComparisonResult(id obj1, id obj2) 
    { 
     char char1 = [(NSString *)obj1 characterAtIndex: 0]; 
     char char2 = [(NSString *)obj2 characterAtIndex: 0]; 

     int index1; 
     for (index1 = 0; index1 < sortOrder.length; index1++) 
      if ([sortOrder characterAtIndex: index1] == char1) 
       break; 

     int index2; 
     for (index2 = 0; index2 < sortOrder.length; index2++) 
      if ([sortOrder characterAtIndex: index2] == char2) 
       break; 

     if (index1 < index2) 
      return NSOrderedAscending; 
     else if (index1 > index2) 
      return NSOrderedDescending; 
     else 
      return [(NSString *)obj1 compare: obj2 options: NSCaseInsensitiveSearch]; 
    }]; 

    for (NSString *s in array) 
     NSLog(@"%@", s); 

    [pool drain]; 
    return 0; 
} 

La sortie est:

2011-08-25 14:19:15.538 NumeralSort[5802:707] Adam 
2011-08-25 14:19:15.540 NumeralSort[5802:707] Bertha 
2011-08-25 14:19:15.540 NumeralSort[5802:707] Colin 
2011-08-25 14:19:15.540 NumeralSort[5802:707] Kraftwerk 
2011-08-25 14:19:15.541 NumeralSort[5802:707] TangerineDream 
2011-08-25 14:19:15.541 NumeralSort[5802:707] Xaver 
2011-08-25 14:19:15.541 NumeralSort[5802:707] Zelda 
2011-08-25 14:19:15.542 NumeralSort[5802:707] 001 
2011-08-25 14:19:15.542 NumeralSort[5802:707] 0ableTypes 
2011-08-25 14:19:15.542 NumeralSort[5802:707] 1And1 
2011-08-25 14:19:15.543 NumeralSort[5802:707] 3SeriesBMW 
2011-08-25 14:19:15.543 NumeralSort[5802:707] 5SeriesBMW 

Ce n'est pas exactement la solution, mais si vous obtenez sur votre chemin.

+0

Ça a marché, merci pour votre aide! – steemcb

+0

comment puis-je l'utiliser dans NSSortDescriptor? – Raj

1

Traduisez les chaînes à comparer en utilisant un tableau de conversion de caractères de 256 (16 bits) (en supposant que vous ayez seulement des caractères ASCII standard). Traduire la plupart des caractères en leurs propres valeurs (ou en minuscules, pour gérer la fonction insensible à la casse en même temps), mais traduire les chiffres en leurs valeurs plus un certain nombre (par exemple, 0xF000). Ensuite, faites la comparaison de chaîne.

Si vous avez des caractères en dehors de la plage ASCII, effectuez la traduction un caractère à la fois, en copiant le caractère exactement (ou inférieur) pour les non-chiffres et en copiant le caractère comme valeur de caractère plus ce grand nombre. chiffres.