Grab random entry in NSDictionary

2019-07-04 18:43发布

问题:

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?

回答1:

See this:

NSArray *array = [dictionary allKeys];
int random = arc4random()%[array count];
NSString *key = [array objectAtIndex:random];


回答2:

NSArray* allKeys = [dictionary allKeys];
id randomKey = allKeys[arc4random_uniform([allKeys count])];
id randomObject = dictionary[randomKey];


回答3:

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.



回答4:

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);
}];


回答5:

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)))]


回答6:

You can create a set and then grab any object from the set.

NSSet *set = [NSSet setWithArray:[myDictionary allKeys]];
NSString *randomKey = [set anyObject];


回答7:

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