कहो कि मेरे पास ऑब्जेक्ट्स के साथ एक सरणी है, 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
रिटर्न पास किया जाता है ।0
0
upper_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_uniform
modulo पूर्वाग्रह से बचने के लिए विधि का उपयोग करता है ।