Objective c 来自NSIndexSet的随机索引

Objective c 来自NSIndexSet的随机索引,objective-c,foundation,nsindexset,Objective C,Foundation,Nsindexset,我需要从NSIndexSet中包含的索引中选择一个随机索引 作为参考,NSSet定义了从集合中拾取任意对象的-anyObject方法()。NSIndexSet中是否有类似的功能?(事实证明,任何对象都不能保证从集合中返回随机对象。) 如果没有,如何实施 注意:我找到了一个实现,但它涉及对索引集元素的迭代。理想情况下,我希望避免枚举 Edit:令我失望的是,NSSet的文档说明,-anyObject不能保证从集合中返回随机对象。不幸的是,同样的结论可以从中得出,首先生成一个介于0和[indexSe

我需要从
NSIndexSet
中包含的索引中选择一个随机索引

作为参考,
NSSet
定义了从集合中拾取任意对象的
-anyObject
方法()。
NSIndexSet
中是否有类似的功能?(事实证明,任何对象都不能保证从集合中返回随机对象。)

如果没有,如何实施

注意:我找到了一个实现,但它涉及对索引集元素的迭代。理想情况下,我希望避免枚举


Edit:令我失望的是,
NSSet
的文档说明,
-anyObject
不能保证从集合中返回随机对象。不幸的是,同样的结论可以从

中得出,首先生成一个介于
0
[indexSet count]-1
之间的随机数

现在从indexSet中获取
randomNum
th索引处的索引。没有类似的
索引index:
方法,但此代码将给出类似的结果:

NSUInteger index = [indexSet firstIndex];

for (NSUInteger i = 0, target = randomNum; i < target; i++)
  index = [indexSet indexGreaterThanIndex:index];
nsuiger index=[indexSet firstIndex];
for(整数i=0,目标=randomNum;i

还可以查看。

首先生成一个介于
0
[indexSet count]-1
之间的随机数

现在从indexSet中获取
randomNum
th索引处的索引。没有类似的
索引index:
方法,但此代码将给出类似的结果:

NSUInteger index = [indexSet firstIndex];

for (NSUInteger i = 0, target = randomNum; i < target; i++)
  index = [indexSet indexGreaterThanIndex:index];
nsuiger index=[indexSet firstIndex];
for(整数i=0,目标=randomNum;i
还可以查看。

无需枚举 您可以在较低级别上为索引手动分配/释放一些内存,而无需任何枚举,这也会显示一个随机索引:

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;
}];
NSIndexSet*_set=…//您的输入索引集
__块NSInteger _计数器=arc4random _均匀((u_int32_t)_set.count);//假设集合中的索引少于UINT32_MAX
NSInteger\u randomIndex=[\u set indexPassingTest:^BOOL(整数idx,BOOL*\u非空停止){
返回--_计数器<0;
}];

注意:如果随机计数器大于set.count/2,则可以使用
NSEnumerationReverse
选项对
O(n/2)
进行优化,但我不担心在这个答案中,如果集合基本上很大,这可能是个好主意,但有几百个索引,即使使用这种笨拙的解决方案,您也不会遇到麻烦。

不使用枚举 您可以在较低级别上为索引手动分配/释放一些内存,而无需任何枚举,这也会显示一个随机索引:

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;
}];
NSIndexSet*_set=…//您的输入索引集
__块NSInteger _计数器=arc4random _均匀((u_int32_t)_set.count);//假设集合中的索引少于UINT32_MAX
NSInteger\u randomIndex=[\u set indexPassingTest:^BOOL(整数idx,BOOL*\u非空停止){
返回--_计数器<0;
}];


注意:如果随机计数器大于set.count/2,则可以使用
NSEnumerationReverse
选项对
O(n/2)
进行优化,但我不担心在这个答案中,如果集合基本上很大,这可能是个好主意,但有几百个索引,使用这种笨拙的解决方案也不会有问题。

除了枚举之外,我看不到任何其他从索引集中获取值的方法。这很遗憾。我希望NSIXDESET,在概念上类似于其他基础集合类的角色,将包含这样一个基本的功能。除非你愿意缓存它。
NSSet
-anyObject
本身并不保证是随机的。@l'l'l自己刚刚发现了这个。在中编辑了它。除了枚举之外,我看不到任何其他从索引集中获取值的方法。这很遗憾。我希望NSIXDESET,在概念上类似于其他基础集合类的角色,将包含这样一个基本的功能。除非你愿意缓存它。
NSSet
-anyObject
本身并不保证是随机的。@l'l'l自己刚刚发现了这个。在中编辑它。