2009-07-10 2 views
3

Когда я с помощью NSArray, это было легко:Как выбрать случайный ключ из 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; 

мне нужно следить за LastIndex, потому что я хочу, ощущение случайности. То есть, я не хочу получать один и тот же элемент дважды подряд. Поэтому это не должно быть «истинной» случайностью.

Из чего я могу судить, NSDictionary не имеет чего-то вроде -объектаAtIndex :. Итак, как я могу это сделать?

ответ

2

Вы можете получить массив ключей с allKeys (неопределенный заказ) или keysSortedByValueUsingSelector (если вы хотите сортировать по значению). Одна вещь, о которой нужно помнить (относительно lastIndex), состоит в том, что даже при сортировке один и тот же индекс может ссылаться на другую пару ключ-значение по мере роста словаря.

Любой из этих (но особенно ключейSortedByValueUsingSelector) будет иметь штраф за производительность.

EDIT: Поскольку словарь не изменен, вы должны просто иметь возможность вызвать allKeys один раз, а затем просто выбрать из него случайные ключи.

+0

Это NSDictionary (не NSMutableDictionary), поэтому он не будет расти. Он будет явно создан при запуске приложения, используя [[NSDictionary alloc] initWithObjectsAndKeys: ..., nil]; – Elliot

+0

Это работает. То, что я сделал, это вызвать allKeys один раз и сохранить его в новом NSARray ivar. Странно, что allKeys не гарантирует возврата ключей в том же порядке, даже если NSDictionary не изменился. Надеюсь, нет никаких проблем с указанием NSArray * на его возвращаемое значение. – Elliot

+0

Я не вижу ничего плохого, держась за возвращаемое значение allKeys в вашем случае. Выделяется новый массив, поэтому результат не указывает непосредственно на внутреннюю структуру данных. –

1

Вы можете использовать код ниже:

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

Чтобы сделать его более эффективным, вы можете кэшировать keys в переменной экземпляра. Надеюсь это поможет.

Смежные вопросы