Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Picking a Random Object in an NSArray

Say I have an array with objects, 1, 2, 3 and 4. How would I pick a random object from this array?

like image 849
Joshua Avatar asked Jul 23 '10 14:07

Joshua


People also ask

Can NSArray contain nil?

arrays can't contain nil.

What is NSArray Objective-C?

The NSArray class contains a number of methods specifically designed to ease the creation and manipulation of arrays within Objective-C programs. Unlike some object oriented programming languages (C# being one example), the objects contained in an array do not all have to be of the same type.

Is NSArray ordered?

An object representing a static ordered collection, for use instead of an Array constant in cases that require reference semantics.

What is array and NSArray in Swift?

Array is a struct, therefore it is a value type in Swift. NSArray is an immutable Objective C class, therefore it is a reference type in Swift and it is bridged to Array<AnyObject> . NSMutableArray is the mutable subclass of NSArray .


2 Answers

@Darryl's answer is correct, but could use some minor tweaks:

NSUInteger randomIndex = arc4random() % theArray.count; 

Modifications:

  • Using arc4random() over rand() and random() is simpler because it does not require seeding (calling srand() or srandom()).
  • The modulo operator (%) makes the overall statement shorter, while also making it semantically clearer.
like image 198
Dave DeLong Avatar answered Oct 13 '22 18:10

Dave DeLong


This is the simplest solution I could come up with:

id object = array.count == 0 ? nil : array[arc4random_uniform(array.count)]; 

It's necessary to check count because a non-nil but empty NSArray will return 0 for count, and arc4random_uniform(0) returns 0. So without the check, you'll go out of bounds on the array.

This solution is tempting but is wrong because it will cause a crash with an empty array:

id object = array[arc4random_uniform(array.count)]; 

For reference, here's the documentation:

u_int32_t arc4random_uniform(u_int32_t upper_bound);  arc4random_uniform() will return a uniformly distributed random number less than upper_bound. 

The man page doesn't mention that arc4random_uniform returns 0 when 0 is passed as upper_bound.

Also, arc4random_uniform is defined in <stdlib.h>, but adding the #import wasn't necessary in my iOS test program.

like image 45
funroll Avatar answered Oct 13 '22 18:10

funroll