2009-07-10 6 views
3

た:NSDictionaryからランダムキーを選択するにはどうすればよいですか?私はNSArrayのを使っていたとき、それは簡単

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

私はランダム感が欲しいので、私はlastIndexのを追跡する必要があります。つまり、同じ要素を2回連続して取得する必要はありません。したがって、「真の」ランダム性であってはなりません。

私が知ることから、NSDictionaryには-objectAtIndex:のようなものはありません。だから私はこれをどのように達成するのですか?

答えて

2

allKeys(未定義の順序)またはkeysSortedByValueUsingSelector(値でソートしたい場合)のキー配列を取得できます。 (lastIndexに関して)注意しなければならないことの1つは、並べ替えを行っても、同じインデックスが辞書の成長に応じて別のキーと値のペアを参照するようになることです。

これらのいずれか(特にkeysSortedByValueUsingSelector)には、パフォーマンス上のペナルティが伴います。

EDIT:辞書は変更できないので、allKeysを一度呼び出すだけで、そこからランダムキーを選択するだけでよいのです。あなたは、インスタンス変数にkeysをキャッシュすることができ、

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

は、それをより効率的にするために:

+0

これはNSDictionary(NSMutableDictionaryではない)なので、成長しません。これは、[[NSDictionary alloc] initWithObjectsAndKeys:...、nil]を使用して、アプリの起動時に明示的に作成されます。 – Elliot

+0

それは動作します。私がやったことは、allKeysを一度呼び、それを新しいNSArray ivarに格納することです。 NSDictionaryが変更されていなくても、allKeysが常に同じ順序でキーを返すことが保証されていないのは奇妙です。しかし、戻り値にNSArray *を指しても問題はありません。 – Elliot

+0

私は、あなたのケースでallKeysの戻り値を保持するのに間違ったことはありません。新しい配列が割り当てられるため、結果は内部データ構造を直接指しません。 –

1

あなたは以下のコードを使用することができます。お役に立てれば。

関連する問題