NSDictionary で完全にランダムなキーを取得する方法はありますか?
NSString *key = [enumeratorForKeysInDictionary nextObject];
非ランダムな方法で辞書を反復処理するこのコードがあります。
すべてのキーを NSSet に追加してから、そこからランダムに取得する必要がありますか?
これを行うより効率的な方法はありますか?
NSDictionary で完全にランダムなキーを取得する方法はありますか?
NSString *key = [enumeratorForKeysInDictionary nextObject];
非ランダムな方法で辞書を反復処理するこのコードがあります。
すべてのキーを NSSet に追加してから、そこからランダムに取得する必要がありますか?
これを行うより効率的な方法はありますか?
これを参照してください:
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];
次のようなこともできます。
NSArray* allKeys = [myDictionary allKeys];
次に、rand() メソッドを使用して、上記の NSArray でランダム インデックスを取得し、ランダム キーを取得できます。
ここでも同じ考えで、キーにランダム インデックスを使用しますが、いくつかの改善があります: (1) 辞書カテゴリ、(2) ネイティブのようなブロック列挙子、(3) 最も重要 - ランダムに列挙するには、既にアクセスしたキーを削除する必要があります. これにより、各キーがランダムに、正確に 1 回アクセスされます (呼び出し元がブロックで stop=YES を設定しない限り)。
//
// 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
次のように呼び出します。
#import "NSDictionary+RandBlockEnum.h"
NSDictionary *dict = @{ @"k1" : @"o1", @"k2" : @"o2", @"k3" : @"o3" };
[dict enumerateKeysAndObjectsRandomlyUsingBlock:^(id key, id object, BOOL *stop) {
NSLog(@"%@, %@", key, object);
}];
セットを作成し、そのセットから任意のオブジェクトを取得できます。
NSSet *set = [NSSet setWithArray:[myDictionary allKeys]];
NSString *randomKey = [set anyObject];