1

に含まれるインデックスからランダムなインデックスを選択する必要がありNSIndexSetます。

参考までに、セットから任意のオブジェクトを選択する方法 (ドキュメントNSSet) を定義します。に同様の機能はありますか? -anyObjectNSIndexSet( -anyObject がセットからランダムなオブジェクトを返すことが保証されていないことがわかりました。)

そうでない場合、どのように実装できますか?

注:ここで実装を見つけましたが、インデックス セットの要素に対する反復処理が含まれます。理想的には、列挙を避けたいと思います。

編集: 残念ながら、セットからランダムなオブジェクトを返すことが保証されていないNSSet状態のドキュメント。残念ながら、ドキュメント-anyObjectから同じ結論を導き出すことができます。NSIndexSet-getIndexes:maxCount:inIndexRange:

4

2 に答える 2

0

0最初にとの間の乱数を生成し[indexSet count]-1ます。

randomNum次に、indexSet から th 番目のインデックスのインデックスを取得します。そのような方法はありませんindexAtIndex:が、このコードは同様の結果をもたらします:

NSUInteger index = [indexSet firstIndex];

for (NSUInteger i = 0, target = randomNum; i < target; i++)
  index = [indexSet indexGreaterThanIndex:index];

この質問も見てください。

于 2016-01-12T12:07:11.597 に答える
0

列挙なし

列挙せずにインデックスに手動でメモリを割り当て/解放することで、下位レベルで何かを行うことができます。これにより、ランダムなインデックスも表示されます。

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、セットが基本的に巨大な場合、この回答でそれを解決することについて心配しませんでした。何百ものインデックスがあるため、この不器用なソリューションでも問題なく使用できます。

于 2016-01-12T12:55:33.047 に答える