2010-09-23 15 views
11

fondamentalement j'ai un NSDictionary avec des clés et des valeurs.NSDictionary tri par clés comme flotteurs

Les clés sont tous des nombres, mais pour le moment, ce sont des chaînes.

Je veux pouvoir les comparer en nombres afin de les trier.

par exemple: Si j'ai un dictionnaire comme celui-ci:

{ 
    "100" => (id)object, 
    "20" => (id)object, 
    "10" => (id)object, 
    "1000" => (id)object, 
} 

Je veux être en mesure de trier comme ceci:

{ 
    "10" => (id)object, 
    "20" => (id)object, 
    "100" => (id)object, 
    "1000" => (id)object, 
} 

Toutes les idées?

Merci

Tom

+1

Avez-vous essayé d'utiliser l'une des méthodes d'instance 'triedArray' de NSArray? Tels que sortedArrayUsingSelector et une méthode maison où vous comparez les valeurs flottantes des chaînes – Jukurrpa

Répondre

14

Vous ne savez pas exactement ce que vous faites - les dictionnaires ne sont pas triés de façon inhérente, il n'y a pas d'ordre de clé stable dans l'implémentation par défaut. Si vous voulez marcher les valeurs par les touches triées, vous pouvez faire quelque chose comme ceci:

NSInteger floatSort(id num1, id num2, void *context) 
{ 
    float v1 = [num1 floatValue]; 
    float v2 = [num2 floatValue]; 
    if (v1 < v2) 
     return NSOrderedAscending; 
    else if (v1 > v2) 
     return NSOrderedDescending; 
    else 
     return NSOrderedSame; 
} 

NSArray *allKeys = [aDictionary allKeys]; 
NSArray *sortedKeys = [allKeys sortedArrayUsingFunction:floatSort context:NULL]; 
for (id key in sortedKeys) 
    id val = [aDictionary objectForKey:key]; 
    … 
+0

c'est ce que je veux :) merci. :) J'ai essayé d'obtenir 'allKeys' du dictionnaire, mais ils étaient toujours des chaînes ... et je ne suis pas trop habile sur le tri. Je savais que je devrais obtenir allKeys sous la forme d'un tableau, le trier et puis sortir chacun dans l'ordre du tableau, mais je ne savais pas comment trier les clés du dictionnaire. Je vous remercie. –

+0

juste ajouter un retour à la fin de la fonction floatSort pour éviter d'éventuels avertissements du compilateur – Vladimir

+0

@Vladimir: Je ne suis pas sûr d'autres compilateurs, mais au moins mon LLVM 1.5 est assez intelligent pour comprendre que la fonction retourne toujours une valeur. – zoul

1

Utilisez compare:options: avec NSNumericSearch.

8

Vous ne pouvez pas trier un dictionnaire, mais vous pouvez obtenir les clés comme un tableau, sorte que, la sortie dans ce commande. sortedArrayUsingComparator fera cela, et vous pouvez comparer les chaînes avec l'option NSNumericSearch.

NSArray* keys = [myDict allKeys]; 
NSArray* sortedArray = [keys sortedArrayUsingComparator:^(id a, id b) { 
    return [a compare:b options:NSNumericSearch]; 
}]; 

for(NSString* aStr in sortedArray) { 
    NSLog(@"%@ has key %@", [myDict objectForKey:aStr], aStr); 
} 
+0

Cela m'a aidé un lot. Code super compact. J'aime ça! Vous connaissez vos trucs zpasternack ... ou au moins vous êtes super copier-coller. ;-) – HotFudgeSunday