कहो कि मेरे पास ऑब्जेक्ट्स के साथ एक सरणी है, 1, 2, 3 और 4. मैं इस सरणी से यादृच्छिक ऑब्जेक्ट कैसे चुनूंगा?
कहो कि मेरे पास ऑब्जेक्ट्स के साथ एक सरणी है, 1, 2, 3 और 4. मैं इस सरणी से यादृच्छिक ऑब्जेक्ट कैसे चुनूंगा?
जवाबों:
@ डैरिल का जवाब सही है, लेकिन कुछ मामूली ट्विक्स का इस्तेमाल कर सकते हैं:
NSUInteger randomIndex = arc4random() % theArray.count;
संशोधन:
arc4random()ओवर का उपयोग करना rand()और random()सरल है क्योंकि इसमें सीडिंग (कॉलिंग srand()या srandom()) की आवश्यकता नहीं होती है ।%), समग्र बयान में कम है, जबकि यह भी अर्थ की दृष्टि से स्पष्ट हो जाता है।0 % 4 = 0, 1 % 4 = 1, 2 % 4 = 2, 3 % 4 = 3, 4 % 4 = 0, 5 % 4 = 1... आप द्वारा सापेक्ष हैं n , अपने सबसे बड़े परिणाम से अधिक होना कभी नहीं होगा n-1 ।
countएक संपत्ति है:@interface NSArray<__covariant ObjectType> : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration> @property (readonly) NSUInteger count;
यह सबसे सरल उपाय है जिसे मैं लेकर आ सकता हूं:
id object = array.count == 0 ? nil : array[arc4random_uniform(array.count)];
यह जांच करने के लिए आवश्यक है count, क्योंकि एक गैर nilलेकिन खाली NSArrayवापस आ जाएगी 0के लिए count, और arc4random_uniform(0)रिटर्न 0। तो चेक के बिना, आप सरणी पर सीमा से बाहर जाएंगे।
यह समाधान लुभावना है लेकिन गलत है क्योंकि यह एक खाली सरणी के साथ दुर्घटना का कारण होगा:
id object = array[arc4random_uniform(array.count)];
संदर्भ के लिए, यहां दस्तावेज है :
u_int32_t
arc4random_uniform(u_int32_t upper_bound);
arc4random_uniform() will return a uniformly distributed random number less than upper_bound.
मैन पेज में उल्लेख नहीं किया गया है कि जब arc4random_uniformरिटर्न पास किया जाता है ।00upper_bound
इसके अलावा, arc4random_uniformमें परिभाषित किया गया है <stdlib.h>, लेकिन जोड़ना #importमेरे iOS परीक्षण कार्यक्रम में आवश्यक नहीं था।
शायद कुछ की तर्ज पर:
NSUInteger randomIndex = (NSUInteger)floor(random()/RAND_MAX * [theArray count]);
यादृच्छिक संख्या जनरेटर (srandomdev (), उदाहरण के लिए) को प्रारंभ करना न भूलें।
नोट: मैंने नीचे दिए गए उत्तर के अनुसार डॉट सिंटैक्स के बजाय -ाउंट का उपयोग करने के लिए अपडेट किया है।
@interface NSArray<ObjectType> (Random)
- (nullable ObjectType)randomObject;
@end
@implementation NSArray (Random)
- (nullable id)randomObject
{
id randomObject = [self count] ? self[arc4random_uniform((u_int32_t)[self count])] : nil;
return randomObject;
}
@end
संपादित करें: Xcode 7. जेनरिक, अशक्तता के लिए अपडेट किया गया
एक यादृच्छिक संख्या उत्पन्न करें और इसे सूचकांक के रूप में उपयोग करें। उदाहरण:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSArray *array = [NSArray arrayWithObjects: @"one", @"two", @"three", @"four", nil];
NSUInteger randomNumber;
int fd = open("/dev/random", O_RDONLY);
if (fd != -1) {
read(fd, &randomNumber, sizeof(randomNumber));
close(fd);
} else {
fprintf(stderr, "Unable to open /dev/random: %s\n", strerror(errno));
return -1;
}
double scaledRandomNumber = ((double)randomNumber)/NSUIntegerMax * [array count];
NSUInteger randomIndex = (NSUInteger)floor(scaledRandomNumber);
NSLog(@"random element: %@", [array objectAtIndex: randomIndex]);
}
return 0;
}
SecRandomCopyBytes()iPhone पर क्रिप्टोग्राफिक रूप से उपयोगी यादृच्छिक संख्या प्राप्त करने के लिए उपयोग कर सकते हैं । मैक पर आप / देव / यादृच्छिक के लिए सीधी पहुँच है।
srand([[NSDate date] timeIntervalSince1970]);
int inx =rand()%[array count];
inx यादृच्छिक संख्या है।
जहां रैंडम () रैंडम पिकिंग फंक्शन से पहले प्रोग्राम में कहीं भी हो सकता है।
ObjectType *objectVarName = [array objectAtIndex:arc4random_uniform((int)(array.count - 1))];
यदि आप उसे एक इंट में डालना चाहते हैं, तो उस के लिए समाधान (तब उपयोगी है, जब आपको एनम-कॉल की संख्या को यादृच्छिक करने के मामले में गैर-अनुक्रमिक संख्याओं की एक सरणी से यादृच्छिक int की आवश्यकता होती है)
int intVarName = (int)[(NSNumber *)[array objectAtIndex:arc4random_uniform((int)(array.count - 1))] integerValue];
स्विफ्ट 4 में:
let array = ["one","two","three","four"]
let randomNumber = arc4random_uniform(UInt32(array.count))
array[Int(randomNumber)]
arc4random_uniformmodulo पूर्वाग्रह से बचने के लिए विधि का उपयोग करता है ।