NSIndexSet “-indexAtIndex:”?

后端 未结 4 1641
执念已碎
执念已碎 2020-12-18 20:57

This feels like a dumb question because it seems to me like my use case must be quite common.

Say I want to represent a sparse set of indexes with an NSIndexSet (whi

相关标签:
4条回答
  • 2020-12-18 21:38

    I believe NSIndexSet stores its indexes using ranges, so there isn't necessarily a quick way to return the nth index. You could enumerate keeping a counter until your counter reaches your target index:

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

    That should give you the 4th index. You could even add the method as a category method if you want:

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

    But, as you said, this may not be the best data structure to use so do consider that more before going with something like this.

    0 讨论(0)
  • 2020-12-18 21:39

    NSIndexSet isn't designed for that sort of access. Usually, you enumerate through the indexes in a set like so:

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

    @Richard points out this for loop is simpler:

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

    There's some block-based methods that are new to NSIndexSet as of Mac OS X 10.6/iOS 4.0, but I haven't reviewed them as of yet.

    It should be trivial to modify the above example to keep a running count of indexes and stop when it reaches the fourth index in the set. ;)

    0 讨论(0)
  • 2020-12-18 21:49

    Say I want to represent a sparse set of indexes with an NSIndexSet (which is of course what it's for).

    [my emphasis]

    Actually, no it's not. The documentation says this:

    You should not use index sets to store an arbitrary collection of integer values because index sets store indexes as sorted ranges.

    So if you are using it to store a sparse array of integers, it is quite inefficient. Also, the only way to get the nth index is to iterate from one end. You'd be better off using an array.

    0 讨论(0)
  • 2020-12-18 21:57

    One more decision:

    - (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;
    }
    
    0 讨论(0)
提交回复
热议问题