2012-06-27 10 views
8

मुझे यकीन नहीं है कि कैसे एनएसएससेट anyObject काम करता है। इसका क्या अर्थ है कि "ऑब्जेक्ट वापस सेट की सुविधा पर चुना जाता है" (NSSet class reference से)?NSSet ऑब्जेक्ट को यादृच्छिक रूप से निकालने के लिए कैसे करें?

आगे, मैं एनएसएससेट से यादृच्छिक रूप से वस्तुओं को कैसे निकाला जा सकता हूं? मैं एक सरणी में allObjects और फिर myArray[arc4random_uniform(x)] प्राप्त करने के बारे में सोच रहा था जहां एक्स सरणी में ऑब्जेक्ट्स की संख्या है।

+0

क्या आप दोहराने के साथ ठीक हैं? – Richard

+0

इसके बारे में उत्सुकता से, मुझे लगता है कि आप किसी भी ऑब्जेक्ट को यादृच्छिक संख्या में कॉल कर सकते हैं लेकिन आपका सरणी समाधान बेहतर लगता है। – Patrick

+0

मुझे लगता है कि एनएसएआरएआरए को एनएसएसएटी में परिवर्तित करने का अनुमान है कि आगे बढ़ने का एक अच्छा तरीका नहीं होगा। –

उत्तर

13

आमतौर पर, NSSet उदाहरण CFHash बैकिंग के साथ बनाए जाते हैं, इसलिए वे हमेशा उस हैश में पहली वस्तु वापस करते हैं, क्योंकि यह देखना सबसे तेज़ है। इसका कारण यह है कि

वापस लौटाई गई वस्तु सेट की सुविधा पर चुनी गई है- चयन को यादृच्छिक होने की गारंटी नहीं है।

ऐसा इसलिए है क्योंकि आप हमेशा नहीं जानते कि इसकी बैकिंग सरणी होगी। आप सभी के लिए, NSSet उदाहरण के लिए आपके पास NSDictionary का बैकिंग है, या कुछ अन्य समान डेटा संरचना है।

तो, अंत में, यदि आप एक NSSet से एक यादृच्छिक वस्तु की जरूरत है, -anyObject का उपयोग नहीं करते हैं, बजाय allObjects: का उपयोग करें और फिर उस सरणी शफ़ल। NSSet Class Reference से

+0

हां! मुझे लगता है कि यह मुझे आज के लिए रेप कैप पर रखता है! –

+0

अब आप सो सकते हैं :) – Anne

+0

@ एनी नोप, अब मेटा पर ऐसा करने का समय है! –

4

प्रलेखन पढ़ता है कि anyObject रिटर्न

सेट में वस्तुओं, या नहीं के बराबर का एक सेट नहीं वस्तुओं है या नहीं। वापस ऑब्जेक्ट सेट की सुविधा पर चुना जाता है- चयन यादृच्छिक होने की गारंटी नहीं है।

अधिकतर काम पर कुछ निर्धारक एल्गोरिदम है।

होगा, आप का सुझाव के रूप में करने के लिए सबसे विश्वसनीय बात है, NSSet विधि allObjects का उपयोग कर एक NSArray बनाने के लिए, और फिर arc4random() % N साथ कि से एक यादृच्छिक तत्व चुनें जहां NNSArray की count है।

+4

मॉड्यूलो पूर्वाग्रह से बचने के लिए, अपने प्रश्न में सुझाए गए फैबियो के रूप में, केवल मॉड्यूलो ऑपरेटर का उपयोग करके arc4random_uniform का उपयोग करने के लिए बेहतर है। – Sven

14

उद्धरण:

वस्तु लौटे सेट की सुविधा के चयन में चुना जाता है यादृच्छिक होने की गारंटी नहीं है।

"अनियमितता" के लिए, [theSet allObjects] का उपयोग कर एक NSArray करने के लिए NSSet परिवर्तित।
अगला, किसी भी वस्तु को 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' –

संबंधित मुद्दे