2012-06-27 50 views
8

我不確定NSSet的anyObject是如何工作的。這是什麼意思「返回的對象是在方便的時候選擇的」(來自NSSet class reference)?NSSet如何隨機提取對象?

此外,如何從NSSet中隨機抽取對象?我正考慮在數組中獲取allObjects,然後myArray[arc4random_uniform(x)]其中x是數組中的對象數。

+0

你可以重複嗎? – Richard

+0

對此我很好奇,我想你可以隨機調用anyObject,但是你的數組解決方案聽起來更好。 – Patrick

+0

我想NSArray來回NSSet將不是一個好的方式來洗牌。 –

回答

13

通常情況下,NSSet實例是使用CFHash支持創建的,因此它們幾乎總是返回該散列中的第一個對象,因爲它是查找速度最快的對象。它說的原因

返回的對象在集合的方便處選擇 - 選擇不保證是隨機的。

是因爲你並不總是知道它會有後備數組。對於您所知道的,您擁有的NSSet實例有支持它的NSDictionary或其他類似的數據結構。

因此,總而言之,如果您需要NSSet中的隨機對象,請不要使用-anyObject,而應使用allObjects:,然後對該數組進行洗牌。從NSSet Class Reference

+0

是的!我認爲這讓我今天的代表帽! –

+0

現在你可以去睡覺:) – Anne

+0

@安妮不,現在是時候在元! –

4

文檔讀取anyObject回報

組中的一個對象,或者爲零,如果該集合包含任何對象。 返回的對象在集合的方便處選擇 - 選擇 不保證是隨機的。

最有可能在工作中有一些確定性算法。

最可靠的事情是,你的建議,使用NSSet方法allObjects創建一個NSArray,然後選擇從一個隨機元素與arc4random() % N其中NNSArraycount

+4

更好地使用arc4random_uniform,而不是使用模運算符,正如fabio在他的問題中所建議的,以避免模偏差。 – Sven

14

引用:

返回被選擇以設定的便利-選擇的對象不被保證是隨機的。

對於 「隨機性」,使用[theSet allObjects]轉換NSSetNSArray
接下來,使用arc4random_uniform()隨機挑選任何對象。

+2

讓我們在這裏公平一點,你還需要以不同的方式初始化隨機數發生器,因爲它確實是隨機的,即使如此,它也是僞隨機的:-) +1 – trumpetlicks

1

我用arc4random()和兩個可變數組來得到一個隨機的和獨特的一組對象:

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

} 

我不知道它將如何有效對大集合,但它的工作對我來說有數量在100個以下的物品中。

+0

會得到除零異常,如果'numberOfObjectsToSelect == selectionPool.count' –