2009-07-10 6 views
3

Quand j'utilisais un NSArray, il était facile:Comment sélectionner une clé aléatoire dans un NSDictionary?

NSArray *array = ... 
lastIndex = INT_MAX; 
... 
int randomIndex; 
do { 
    randomIndex = RANDOM_INT(0, [array count] - 1); 
} while (randomIndex == lastIndex); 
NSLog(@"%@", [array objectAtIndex:randomIndex]); 
lastIndex = randomIndex; 

J'ai besoin de garder une trace du lastIndex parce que je veux le sentiment de hasard. C'est-à-dire que je ne veux pas avoir le même élément deux fois de suite. Cela ne devrait donc pas être un "vrai" caractère aléatoire. De ce que je peux dire, NSDictionary n'a pas quelque chose comme -objectAtIndex :. Alors, comment puis-je accomplir cela?

Répondre

2

Vous pouvez obtenir un tableau de clés avec allKeys (ordre indéfini) ou keysSortedByValueUsingSelector (si vous souhaitez trier par valeur). Une chose à garder à l'esprit (en ce qui concerne lastIndex) est que même avec le tri, le même index peut faire référence à une paire clé-valeur différente à mesure que le dictionnaire se développe.

L'un ou l'autre de ces paramètres (mais surtout keysSortedByValueUsingSelector) est assorti d'une pénalité de performance.

EDIT: Étant donné que le dictionnaire n'est pas modifiable, vous devriez pouvoir appeler tous les clés une seule fois, puis sélectionner des clés aléatoires.

+0

C'est un NSDictionary (pas un NSMutableDictionary), donc ça ne va pas se développer. Il sera explicitement créé au lancement de l'application, en utilisant [[NSDictionary alloc] initWithObjectsAndKeys: ..., nil]; – Elliot

+0

Cela fonctionne. Ce que j'ai fait, c'est appeler tous les Keys une fois et le stocker dans un nouvel ivar NSArray. Il est étrange que tous les clés ne soient pas garanties de toujours retourner les clés dans le même ordre, même si le NSDictionary est inchangé. Heureusement, il n'y a aucun problème à pointer un NSArray * à sa valeur de retour, cependant. – Elliot

+0

Je ne vois rien de mal à conserver la valeur de retour allKeys dans votre cas. Un nouveau tableau est alloué, de sorte que le résultat ne pointe pas directement vers une structure de données interne. –

1

Vous pouvez utiliser le code ci-dessous:

- (YourObjectType *)getRandomObjectFromDictionary:(NSDictionary *)dictionary 
{ 
    NSArray *keys = dictionary.allKeys; 
    return dictionary[keys[arc4random_uniform((int)keys.count)]]; 
} 

Pour le rendre plus efficace, vous pouvez mettre en cache keys dans une variable d'instance. J'espère que cela t'aides.

Questions connexes