একটি এনএসআরিতে একটি র্যান্ডম অবজেক্ট বাছাই করা


83

বলুন, আমার কাছে 1, 2, 3 এবং 4 অবজেক্টের সাথে একটি অ্যারে রয়েছে আমি কীভাবে এই অ্যারে থেকে এলোমেলো বস্তুটি বেছে নেব?


এখানে সমস্ত উত্তর সঠিক, তবে আরও আপ-টু-ডেট সমাধানের জন্য আমার উত্তরটি এখানে দেখুন । এটি arc4random_uniformমডুলো পক্ষপাতিত্ব এড়ানোর জন্য পদ্ধতিটি ব্যবহার করে ।
আদম

এই প্রশ্নের উত্তর নয়, তবে একটি আকর্ষণীয় বিষয় - অন্যান্য ফাউন্ডেশন সংগ্রহের (এনএসএসেট এনএসএইচএসটিবেল) পদ্ধতিগুলি "যেকোনো অবজেক্ট" রয়েছে যা সেট / হ্যাশ টেবিল থেকে একটি স্বেচ্ছাসেবী (এলোমেলো) অবজেক্ট পড়ে। নীচের পরামর্শ অনুসরণ করে, কেউ এনএসআরির এক্সটেনশনে এই পদ্ধতিটি প্রয়োগ করতে পারে।
মোটি শ্নের

উত্তর:


192

@ ড্যারিলের উত্তরটি সঠিক, তবে কিছু ছোটখাটো টুইট ব্যবহার করতে পারে:

NSUInteger randomIndex = arc4random() % theArray.count;

পরিবর্তনসমূহ:

  • arc4random()ওভার ব্যবহার করা সহজ rand()এবং random()সহজ কারণ এর জন্য বীজ বপনের প্রয়োজন নেই (কলিং srand()বা srandom())।
  • ফরম অপারেটরের ( %), সামগ্রিক বিবৃতি খাটো করে তোলে যখন এটি শব্দার্থগতভাবে পরিষ্কার করে।

27
Arc4random ম্যান পৃষ্ঠা থেকে: c c arc4random ()% উপরের_বাউন্ড '' এর মতো নির্মাণগুলির উপর আরক 4 ব্র্যান্ডম_উনিফর্ম () বাঞ্ছনীয় কারণ যখন উপরের চৌম্বকটি দুটির শক্তি না হয় তখন "মডুলো বায়াস" এড়ানো হয়।
ম্যাক্স ইয়ানকভ

@collibhoy না, কারণ 0 % 4 = 0, 1 % 4 = 1, 2 % 4 = 2, 3 % 4 = 3, 4 % 4 = 0, 5 % 4 = 1... আপনি modulo যদি এন , আপনার বৃহত্তম ফলাফলের চেয়ে অনেক বেশী হতে হবে না এন -1
ডেভ দেলং

4
@ ডেভিডলং উত্স কোড অনুসারে, countএকটি সম্পত্তি:@interface NSArray<__covariant ObjectType> : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration> @property (readonly) NSUInteger count;
মাইকহো

17

এটি আমি নিয়ে আসতে পারে সবচেয়ে সহজ সমাধান:

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আমার আইওএস পরীক্ষার প্রোগ্রামটি যুক্ত করা দরকার ছিল না।


11

এর লাইন ধরে সম্ভবত কিছু:

NSUInteger randomIndex = (NSUInteger)floor(random()/RAND_MAX * [theArray count]);

এলোমেলো সংখ্যা জেনারেটর (ভ্রমনডেমদেব () উদাহরণস্বরূপ) আরম্ভ করতে ভুলবেন না।

দ্রষ্টব্য: আমি নীচের উত্তর অনুসারে ডট সিনট্যাক্সের পরিবর্তে-অ্যাকাউন্ট ব্যবহার করতে আপডেট করেছি।


9
@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

সম্পাদনা করুন: এক্সকোড 7. এর জন্য আপডেট হয়েছে Gen


1

একটি এলোমেলো সংখ্যা তৈরি করুন এবং এটি সূচক হিসাবে ব্যবহার করুন। উদাহরণ:

#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()আইফোনে যেকোন উপায়ে ক্রিপ্টোগ্রাফিকভাবে দরকারী র্যান্ডম নম্বর পেতে ব্যবহার করতে পারেন । ম্যাকে আপনার / dev / এলোমেলোভাবে সরাসরি অ্যাক্সেস রয়েছে।

আমি মনে করি যে প্রশ্নের মূল পয়েন্টটি অ্যারে থেকে কোনও এলোমেলো আইটেম কীভাবে চয়ন করবেন তা দেখানো এবং এই উত্তরটি সর্বোত্তম তথ্য দেয় না।
বিকার

আমি এই রসিকতাটি বেশ পছন্দ করি, তবে যারা এটি পায় না তাদের সহায়তা করার জন্য আমি এটিকে ভোট দিয়েছি।
স্টিগ ব্রুটাসেট

0
 srand([[NSDate date]  timeIntervalSince1970]);

 int inx =rand()%[array count];

inx হল এলোমেলো সংখ্যা।

যেখানে srand () এলোমেলো বাছাইয়ের ফাংশনের আগে প্রোগ্রামের যে কোনও জায়গায় থাকতে পারে।


0
ObjectType *objectVarName = [array objectAtIndex:arc4random_uniform((int)(array.count - 1))];

যদি আপনি এটি কোনও অন্তর্ভুক্ত করতে চান, তবে এর সমাধান এখানে দেওয়া হয়েছে (এনাম কলকে এলোমেলো করার ক্ষেত্রে, যখন আপনাকে নন-সিক্যুয়াল সংখ্যাগুলির অ্যারে থেকে একটি এলোমেলো ইনট প্রয়োজন হয় তার জন্য দরকারী)

int intVarName = (int)[(NSNumber *)[array objectAtIndex:arc4random_uniform((int)(array.count - 1))] integerValue];

0

সুইফ্ট 4 এ:

let array = ["one","two","three","four"]
let randomNumber = arc4random_uniform(UInt32(array.count))

array[Int(randomNumber)]

4
দয়া করে পর্যালোচনা করুন আমি কীভাবে একটি ভাল উত্তর লিখি । কোড-কেবল উত্তরগুলি নিরুৎসাহিত করা হয়েছে কারণ তারা কীভাবে প্রশ্নটিতে সমস্যাটি সমাধান করে তা ব্যাখ্যা করে না। 7 বছর বয়সী এই প্রশ্নটি ইতিমধ্যে যা করেছে এবং এটি কীভাবে উত্তর দেয় তা কী করে তা ব্যাখ্যা করার জন্য আপনার উত্তরটি আপডেট করতে হবে
FluffyKitten
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.