Je l'ai fait:
NSArray *sortedLetters = nil;
NSMutableSet *set = [[NSMutableSet alloc] init];
NSCharacterSet *charSet = [NSCharacterSet characterSetWithCharactersInString:@"AZERTYUIOPQSDFGHJKLMWXCVBN"];
for (RealmContact *contact in _dataSource)
{
NSString *firName = [[contact firstName] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if ([firName length])
{
unichar c = [[firName uppercaseString] characterAtIndex:0];
if ([charSet characterIsMember:c])
{
[set addObject:[NSString stringWithFormat: @"%C", c]];
}
else
{
[set addObject:@"#"];
}
}
}
sortedLetters = [[set allObjects] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
Quelles sont les différences?
• J'ai utilisé un NSSet
au lieu d'un NSDictionary
pour l'unicité des premières lettres. Je trouve inutile d'utiliser un NSDictionary
avec une valeur inutilisée et juste pour l'unicité des touches. J'ai utilisé stringByTrimmingCharactersInSet:
au lieu de stringByReplacingOccurrencesOfString:withString:
. En théorie, le code de stringByTrimmingCharactersInSet:
doit s'arrêter au premier caractère qui n'est pas de l'ensemble, et ne pas continuer jusqu'à la fin de la chaîne comme stringByReplacingOccurrencesOfString:withString:
.
• Je suppose que characterIsMember:
est plus rapide qu'un Regex/Predicate.
• Puisque vous ne vous intéressez qu'aux majuscules, je les ai traduites avant de faire le test, et non après, ce qui pourrait aussi accélérer le prédicat dans votre cas.
En outre, de petites erreurs sur votre code:
if (contact.firstName.length>0 && result)
et
[nameDic setObject:@"firstletter" forKey:[[contact.firstName substringToIndex:1]uppercaseString]];
doivent utiliser firName
au lieu de contact.firstName
.
Sur this test sample, ma solution semble être plus rapide que le vôtre (x10). J'ai testé rapidement sur une application OS X (pas iOS). Je n'ai pas fait beaucoup de tests, mais ça vaut le coup d'essayer.
Je ne sais pas si juste pour la question, mais l'optimisation de code que vous pourriez faire:
NSString *stringToTest = nil;
if ([sortBy isEqualToString:@"FirstName"])
{
stringToTest = contact.firstName;
}
else if ([sortBy isEqualToString:@"LastName"])
{
stringToTest = contact.lastName;
}
else if ([sortBy isEqualToString:@"Company"])
{
stringToTest = contact.companyName;
}
stringToTest = [stringToTest stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if ([stringToTest length])
{
//Do the code with stringToTest
}
Il est pour la duplication moins de code et utiliser aussi if/else
Je l'ai fait : https://pastebin.com/ixHsPSxh Testé sur OSX Simulator, semble plus rapide (x10, mais n'a pas fait plus de tests). Aussi, petite erreur sur votre code: 'if (contact.firstName.length> 0 && result)' et '[nameDic setObject: @" firstletter "forKey: [[contact.firstName sous-chaîneToIndex: 1] majusculeString]];' devrait utiliser 'firName' au lieu de' contact.firstName'. – Larme