在NSArray中select一个随机对象
说我有一个数组与对象, 1,2,3和4.我怎么会从这个数组中挑选一个随机对象?
Darryl的回答是正确的,但可以使用一些小的调整:
NSUInteger randomIndex = arc4random() % [theArray count];
修改:
- 在
rand()
和random()
使用arc4random()
更简单,因为它不需要种子(调用srand()
或srandom()
)。 - 模运算符 (
%
)使总体语句更短,同时使语义更清晰。 -
theArray.count
是错误的。 它会工作,但count
没有在NSArray
上声明为NSArray
,因此不应该通过点语法来调用。 它的作用只是编译器如何解释点语法的副作用。
这是我能想到的最简单的解决scheme:
id object = array.count == 0 ? nil : array[arc4random_uniform(array.count)];
有必要检查count
因为非零,但空的NSArray
将返回0
为count
,和arc4random_uniform(0)
返回0
。 所以没有检查,你会超出arrays的界限。
这个解决scheme是诱人的,但是是错误的,因为它会导致一个空数组的崩溃:
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.
手册页没有提到,当0
作为upper_bound
传递时, arc4random_uniform
返回0
。
另外,在<stdlib.h>
定义了arc4random_uniform
,但在我的iOStesting程序中添加#import
并不是必需的。
也许是沿着以下方向的东西:
NSUInteger randomIndex = (NSUInteger)floor(random()/RAND_MAX * [theArray count]);
例如,不要忘记初始化随机数发生器(srandomdev())。
注意:根据下面的答案,我更新了使用-count而不是点语法。
@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.generics,可空性
生成一个随机数并将其用作索引。 例:
#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; }
ObjectType *objectVarName = [array objectAtIndex:arc4random_uniform((int)(array.count - 1))];
如果你想把它转换为一个int,下面是这个解决scheme(当你需要一个非序列号的数组中的随机int,在随机化enum调用的情况下等等)
int intVarName = (int)[(NSNumber *)[array objectAtIndex:arc4random_uniform((int)(array.count - 1))] integerValue];
srand([[NSDate date] timeIntervalSince1970]); int inx =rand()%[array count];
inx是随机数。
srand()可以在随机选取函数之前的程序中的任何地方。
在Swift 4:
let array = ["one","two","three","four"] let randomNumber = arc4random_uniform(UInt32(array.count)) array[Int(randomNumber)]