15

私のユースケースはかなり一般的であるに違いないように思えるので、これはばかげた質問のように感じます。

NSIndexSet(もちろんそれが目的です)を使用して、まばらなインデックスのセットを表現したいとします。私は-firstIndex最低のものと-lastIndex最高のものを取得するために使用できますが、その「インデックス」を前提として、中央に単一の任意のインデックスを取得するための標準的な方法は何ですか?ドキュメントは私を不明確にしました。

たとえば、インデックスが{0、5、8、10、12、28}で設定されていて、「4番目のインデックスを教えて」と言いたい場合、10(または12と思います)が返されると思います。私がゼロを数えるかどうかにもよりますが、それには入りません、あなたは私が何を意味するか知っています)。

インデックスセット全体で「列挙」を行っていないことに注意してください。ある時点で、セット内のn番目のインデックスが番号順に何であるかを知りたいだけです。

たぶん私のデータ構造は間違っています(「セット」は通常、そのような順序付けられたアクセス用に設計されていません)が、NSIndexArrayについて話すことはないようです。

明らかな何かが欠けていますか?

ありがとう!

4

4 に答える 4

7

NSIndexSetそのようなアクセス用に設計されていません。通常、次のようにセット内のインデックスを列挙します。

NSUInteger idx = [theSet indexGreaterThanOrEqualToIndex: 0];
while (idx != NSNotFound) {
    // idx equals the next index in the set.
    idx = [theSet indexGreaterThanIndex: idx];
}

for@Richardは、このループの方が簡単だと指摘しています。

for (NSUInteger i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex:i]) {
    // i equals the next index in the set.
}

Mac OS X 10.6 / iOS 4.0の時点で新しいブロックベースの方法がいくつかありますNSIndexSetが、私はまだそれらをレビューしていません。

上記の例を変更して、インデックスの実行カウントを維持し、セットの4番目のインデックスに達したときに停止するのは簡単なことです。;)

于 2010-12-28T16:34:21.490 に答える
5

範囲を使用してインデックスを格納すると思うNSIndexSetので、インデックスを返すための迅速な方法は必ずしもありませんnth。カウンターがターゲットインデックスに到達するまで、カウンターを保持することを列挙できます。

NSUInteger index = [indexSet firstIndex];

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

それはあなたに4番目のインデックスを与えるはずです。必要に応じて、メソッドをカテゴリメソッドとして追加することもできます。

- (NSUInteger)indexAtIndex:(NSUInteger)anIndex
{
    if (anIndex >= [self count])
      return NSNotFound;

    NSUInteger index = [indexSet firstIndex];
    for (NSUInteger i = 0; i < anIndex; i++)
      index = [self indexGreaterThanIndex:index];
    return index;
}

しかし、あなたが言ったように、これは使用するのに最適なデータ構造ではないかもしれないので、このようなものを使う前にもっとそれを考慮してください。

于 2010-12-28T16:37:46.587 に答える
3

NSIndexSet (もちろんその目的です)を使用して、まばらなインデックスのセットを表現したいとします。

[私の強調]

実際、そうではありません。ドキュメントには次のように書かれています。

インデックスセットはインデックスをソートされた範囲として格納するため、インデックスセットを使用して整数値の任意のコレクションを格納しないでください。

したがって、整数のスパース配列を格納するためにそれを使用している場合、それは非常に非効率的です。また、n番目のインデックスを取得する唯一の方法は、一方の端から反復することです。配列を使用したほうがよいでしょう。

于 2010-12-28T16:42:21.363 に答える
0

もう1つの決定:

- (NSUInteger)indexAtIndex:(NSUInteger)index {
   __block NSUInteger result = NSNotFound;
   __block NSUInteger aCounter = 0;

   [self enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) {
      if (aCounter == index) {
         result = idx;
         *stop = YES;

      } else {
         aCounter++;
      }
   }];

   return result;
}
于 2017-09-08T20:54:51.030 に答える