NSSetがどのように機能するかはわかりませんanyObject。「返されるオブジェクトはセットの都合の良いときに選択される」(NSSetクラス参照から)とはどういう意味ですか?
さらに、NSSetからオブジェクトをランダムに抽出するにはどうすればよいですか?allObjects私は配列を取得することを考えていましたmyArray[arc4random_uniform(x)]。ここで、xは配列内のオブジェクトの数です。
NSSetがどのように機能するかはわかりませんanyObject。「返されるオブジェクトはセットの都合の良いときに選択される」(NSSetクラス参照から)とはどういう意味ですか?
さらに、NSSetからオブジェクトをランダムに抽出するにはどうすればよいですか?allObjects私は配列を取得することを考えていましたmyArray[arc4random_uniform(x)]。ここで、xは配列内のオブジェクトの数です。
NSSetクラスリファレンスからの引用:
返されるオブジェクトは、セットの都合に合わせて選択されます。選択がランダムであるとは限りません。
「ランダム性」についてはNSSet、NSArrayをusingに変換し[theSet allObjects]ます。
次に、を使用して任意のオブジェクトをランダムに選択しますarc4random_uniform()。
通常、NSSetインスタンスはCFHashバッキングを使用して作成されるため、検索が最も速いため、ほとんどの場合、そのハッシュの最初のオブジェクトが返されます。それが言う理由
返されるオブジェクトは、セットの都合に合わせて選択されます。選択がランダムであるとは限りません。
バッキングアレイがあることを常に知っているとは限らないからです。ご存知のとおり、NSSetインスタンスにはNSDictionary裏付けがあるか、他の同様のデータ構造があります。
したがって、結論として、からランダムなオブジェクトが必要な場合は、をNSSet使用せず-anyObject、代わりにallObjects:その配列を使用してシャッフルします。
ドキュメントはそれをanyObject返します
セット内のオブジェクトの1つ、またはセットにオブジェクトが含まれていない場合はnil。返されるオブジェクトは、セットの都合に合わせて選択されます。選択がランダムであるとは限りません。
ほとんどの場合、決定論的アルゴリズムが機能しています。
最も信頼できる方法は、ご提案のとおり、メソッドNSArrayを使用して作成し、その中からランダムな要素を選択することです。ここで、はです。NSSetallObjectsarc4random() % NNcountNSArray
arc4random()と2つの可変配列を使用して、ランダムで一意のオブジェクトのセットを取得します。
NSMutableArray *selectionPool = ...;
int numberOfObjectsToSelect = x;
NSMutableArray *selectedObjects = [[NSMutableArray alloc] initWithCapacity:numberOfObjectsToSelect];
int modulus = selectionPool.count - 1;
for (int i = 0; i < numberOfObjectsToSelect; i++) {
int j = arc4random() % (modulus--);
[selectedObjects addObject:[selectionPool objectAtIndex:j]];
[selectionPool removeObjectAtIndex:j];
}
大規模なコレクションでどれほど効率的かはわかりませんが、数百のオブジェクトの数が少ないコレクションではうまくいきました。