Is there a way to grab a totally random key in the NSDictionary?
NSString *key = [enumeratorForKeysInDictionary nextObject];
I have this code which iterates over the dictionary in a non-random way.
Should I add all the keys to an NSSet and then pull randomly from there?
Is there a more efficient way to do this?
See this:
NSArray *array = [dictionary allKeys];
int random = arc4random()%[array count];
NSString *key = [array objectAtIndex:random];
NSArray* allKeys = [dictionary allKeys];
id randomKey = allKeys[arc4random_uniform([allKeys count])];
id randomObject = dictionary[randomKey];
You can also try something like this:
NSArray* allKeys = [myDictionary allKeys];
Then you can c method rand() to get a random index in the above NSArray to get the random key.
Same idea here, using a random index into keys, but a few improvements: (1) a dictionary category, (2) a block enumerator, like the native, (3) most important - to enumerate randomly, we must eliminate keys already visited. This will visit each key randomly, exactly once (unless the caller sets stop=YES in the block):
//
// NSDictionary+RandBlockEnum.h
//
#import <Foundation/Foundation.h>
@interface NSDictionary (RandBlockEnum)
- (void)enumerateKeysAndObjectsRandomlyUsingBlock:(void (^)(id, id, BOOL *))block;
@end
//
// NSDictionary+RandBlockEnum.m
//
#import "NSDictionary+RandBlockEnum.h"
@implementation NSDictionary (RandBlockEnum)
- (void)enumerateKeysAndObjectsRandomlyUsingBlock:(void (^)(id, id, BOOL *))block {
NSMutableArray *keys = [NSMutableArray arrayWithArray:[self allKeys]];
BOOL stop = NO;;
while (keys.count && !stop) {
id randomKey = keys[arc4random_uniform(keys.count)];
block(randomKey, self[randomKey], &stop);
[keys removeObject:randomKey];
}
}
@end
Call it like this:
#import "NSDictionary+RandBlockEnum.h"
NSDictionary *dict = @{ @"k1" : @"o1", @"k2" : @"o2", @"k3" : @"o3" };
[dict enumerateKeysAndObjectsRandomlyUsingBlock:^(id key, id object, BOOL *stop) {
NSLog(@"%@, %@", key, object);
}];
Modern, one-line version of @BestCoder's answer:
Objective-C
dictionary.allKeys[arc4random_uniform(dictionary.allKeys.count)]
Swift
Array(dictionary.keys)[Int(arc4random_uniform(UInt32(dictionary.keys.count)))]
You can create a set and then grab any object from the set.
NSSet *set = [NSSet setWithArray:[myDictionary allKeys]];
NSString *randomKey = [set anyObject];
SWIFT 4
you have a dictionary
let ads = _segueDataFromHomeToGuessMatch_NSType[Constants.Matches.ads] as! NSDictionary
get a random key value like this
let rd_ad_key = ads.allKeys[Int(arc4random_uniform(UInt32(ads.count)))] as! String
get value of the random key like this
let rd_ad_value = ads[rd_ad_key] as! String