0

Je développe une application iPhone en ObjectiveC dans lequel j'ai un tableau ayant alphanumériques, des données multilingues, caractères spéciaux comme indiqué ci-dessous:tableau de tri ayant des caractères spéciaux, des chiffres, l'anglais et la chaîne arabe en ObjectiveC

(
    { 
     name = “#”; 
    }, 
    { 
     name = “iPad”; 
    }, 
    { 
     name = “عينة”; 
    }, 
    { 
     name = “1”; 
    }, 
    { 
     name = “أ”; 
    }, 
    { 
     name = “10”; 
    }, 

) 

Le tri doit me fournir des résultats comme ci-dessous,

(
    { 
     name = “iPad”; 
    }, 
    { 
     name = “أ”; 
    }, 
    { 
     name = “عينة”; 
    } 
    { 
     name = “#”; 
    }, 
    { 
     name = “1”; 
    }, 
    { 
     name = “10”; 
    }, 

) 

Un premier moyen anglais et en arabe devrait être en ordre alphabétique ascendant puis caractères spéciaux, de chiffres dans l'ordre croissant.

+1

Vous devez nous dire ce langage de programmation et le système de ce code est pour. Difficile pour nous de répondre autrement. Mettez à jour la question à l'aide du bouton [Modifier]. –

+0

Son pour l'objectif c @ BrianTompsett- 汤 莱恩. Désolé de ne pas mentionner à la hâte. – cjd

+0

Je pense qu'une façon est de créer 4 tableaux séparés à partir de ce tableau combiné, puis de trier chacun d'entre eux individuellement et de les combiner à la fin. Mais je ne suis pas sûr de savoir comment je peux le faire. – cjd

Répondre

0

J'obtenu la solution en utilisant l'expression régulière comme ci-dessous,

NSMutableArray *aMutArrArabic = [[NSMutableArray alloc] init]; 
    for(NSDictionary *aDictObj in mutArrAddCard) 
    { 
     NSError *error = NULL; 
     NSRegularExpression *aRegexObj = [NSRegularExpression regularExpressionWithPattern:@"^[ء-ي]+$" 
                         options:NSRegularExpressionCaseInsensitive 
                         error:&error]; 
     NSArray *aArrMatches = [aRegexObj matchesInString:aDictObj[@"name"] 
                options:0 
                range:NSMakeRange(0, [aDictObj[@"name"] length])]; 

     if([aArrMatches count] > 0) 
     { 
      [aMutArrArabic addObject:aDictObj]; 
     } 
    } 

De cette façon, j'ai réussi à obtenir tous les tableaux en utilisant leur expression régulière pertinente.

+0

Toute autre manière, meilleure et efficace, de le faire est la bienvenue. – cjd

0

Il pourrait y avoir une amélioration, par ce que vous pouvez faire avec sortedArrayUsingComparator: et un bloc de comparateur personnalisé.

Idée principale:
- Récupère le premier caractère de la chaîne.
- Déterminer ce qu'est son "kind" (Lettre, Arabe, Numéro, Autre)
- Trier en conséquence.

J'ai commencé avec ces « genre »:

typedef enum : NSUInteger { 
    CharacterOfKindArabic, 
    CharacterOfKindNumerical, 
    CharacterOfKindLetter, 
    CharacterOfKindOther 
} CharacterOfKind; 

Et utiliser cette méthode pour obtenir le CharacterOfKind:

-(CharacterOfKind)retrieveFirstCharacterKindFromString:(NSString *)string 
{ 
    if ([string length]) 
    { 
     unichar unicharacter = [string characterAtIndex:0]; 
     if (unicharacter >= 0x600 && unicharacter <= 0x6ff) 
      return CharacterOfKindArabic; 
     if (unicharacter >= 0x750 && unicharacter <= 0x77f) 
      return CharacterOfKindArabic; 
     if (unicharacter >= 0xfb50 && unicharacter <= 0xfc3f) 
      return CharacterOfKindArabic; 
     if (unicharacter >= 0xfe70 && unicharacter <= 0xfefc) 
      return CharacterOfKindArabic; 

     NSString *firstChar = [string substringToIndex:1]; 
     if ([firstChar rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet] options:0].location != NSNotFound) 
      return CharacterOfKindNumerical; 
     if ([firstChar rangeOfCharacterFromSet:[NSCharacterSet letterCharacterSet] options:0].location != NSNotFound) 
      return CharacterOfKindLetter; 
     return CharacterOfKindOther; 
    } 
    return CharacterOfKindOther; 
} 

Je ne parle pas l'arabe, et je jamais eu à code avec l'arabe texte. J'ai donc pris ces infos de "gamme de caractères" du net. J'ai lu quelque chose sur Objective-C ici sur StackOverflow, mais je n'ai pas pu le récupérer. Peut-être que ma mémoire joue avec moi, mais la portée peut avoir changé (plus de gammes ajoutées). Je trouve la méthode un peu moche, mais c'est pour avoir le point principal.

NSString *kName = @"name"; 
NSArray *arrayToSort = @[@{kName:@"#"}, 
         @{kName:@"iPhone"}, 
         @{kName:@"iPad"}, 
         @{kName:@"عينة"}, 
         @{kName:@"1"}, 
         @{kName:@"أ"}, 
         @{kName:@"10"}]; 

NSLog(@"arrayToSort: %@", arrayToSort); 

NSArray *typeSort = @[@(CharacterOfKindLetter), @(CharacterOfKindArabic), @(CharacterOfKindOther), @(CharacterOfKindNumerical)]; 
NSArray *sortedArray = [arrayToSort sortedArrayUsingComparator:^NSComparisonResult(NSDictionary * _Nonnull obj1, NSDictionary * _Nonnull obj2) 
{ 
    NSString *firstString = obj1[kName]; 
    NSString *secondString = obj2[kName]; 
    CharacterOfKind firstCharType = [self retrieveFirstCharacterKindFromString:firstString]; 
    CharacterOfKind secondCharType = [self retrieveFirstCharacterKindFromString:secondString]; 

    if (firstCharType == secondCharType) //Same Kind of first characters, do a normal "compare" 
    { 
     return [firstString compare:secondString]; 
    } 
    else //Do a custom compare according typeSort 
    { 
     //Returns correctly according to the order set in typeSort 
     return [@([typeSort indexOfObject:@(firstCharType)]) compare:@([typeSort indexOfObject:@(secondCharType)])]; 
    } 
}]; 

NSLog(@"SortedArray: %@", sortedArray); 

Sortie:

>>>arrayToSort: (
     { 
     name = "#"; 
    }, 
     { 
     name = iPhone; 
    }, 
     { 
     name = iPad; 
    }, 
     { 
     name = "\U0639\U064a\U0646\U0629"; 
    }, 
     { 
     name = 1; 
    }, 
     { 
     name = "\U0623"; 
    }, 
     { 
     name = 10; 
    } 
) 
>>>SortedArray: (
     { 
     name = iPad; 
    }, 
     { 
     name = iPhone; 
    }, 
     { 
     name = "\U0623"; 
    }, 
     { 
     name = "\U0639\U064a\U0646\U0629"; 
    }, 
     { 
     name = "#"; 
    }, 
     { 
     name = 1; 
    }, 
     { 
     name = 10; 
    } 
)