不枚举
您可以在没有任何枚举的情况下手动为索引分配/释放一些内存,从而在较低级别上做一些事情,这也提供了一个随机索引:
NSIndexSet *_set = ... // your input index set
NSUInteger *_integerCArray = malloc(_set.count * sizeof(NSUInteger));
#if __LP64__
NSRange _indicesRange = NSMakeRange(0, UINT64_MAX);
#else
NSRange _indicesRange = NSMakeRange(0, UINT32_MAX);
#endif
[_set getIndexes:_integerCArray maxCount:_set.count inIndexRange:&_indicesRange];
NSInteger _randomIndex = _integerArray[arc4random_uniform((u_int32_t)_set.count)]; // the random index
free(_integerCArray), _integerCArray = nil;
带枚举
我知道您告诉过您对枚举不感兴趣,公平地说,这不是一种真正有效的方法,但它也绝对可以根据需要为您提供随机索引,并且更好地阅读并且内存管理更安全这个案例:
NSIndexSet *_set = ... // your input index set
__block NSInteger _counter = arc4random_uniform((u_int32_t)_set.count); // assume there are fewer indices in the set than UINT32_MAX
NSInteger _randomIndex = [_set indexPassingTest:^BOOL(NSUInteger idx, BOOL * _Nonnull stop) {
return --_counter < 0;
}];
注意:这个想法也可以优化,如果随机计数器大于,则O(n/2)
使用选项,但我不担心在这个答案中,如果集合基本上很大,这可能是一个好主意,但有一些数百个索引,即使使用这种笨拙的解决方案,您也不会遇到麻烦。NSEnumerationReverse
_set.count / 2