15

这感觉像是一个愚蠢的问题,因为在我看来,我的用例一定很常见。

假设我想用 NSIndexSet 表示一组稀疏的索引(这当然是它的用途)。我可以-firstIndex用来获取最低-lastIndex的和最高的,但是在给定它的“索引”的情况下,在中间获取单个任意索引的规范方法是什么?文档让我不清楚。

例如,如果我有一个索引集 { 0, 5, 8, 10, 12, 28 },我想说“给我第四个索引”,我希望得到 10(或 12 我想取决于我是否计算第零个,但我们不要进入那个,你知道我的意思)。

请注意,我没有对整个索引集进行“枚举”。在给定的时间点,我只想按数字顺序知道集合中的第 n 个索引是什么。

也许我的数据结构是错误的(“set”通常不是为这种有序访问而设计的),但似乎没有 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];
}

@Richard 指出这个for循环更简单:

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的,但我还没有审查它们。

修改上面的示例以保持索引的运行计数并在到达集合中的第四个索引时停止应该是微不足道的。;)

于 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];

那应该给你第四个索引。如果需要,您甚至可以将该方法添加为类别方法:

- (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

又一个决定:

- (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 回答