Enumerate NSArray starting at givven index searching both ways (no wrap around)

大城市里の小女人 提交于 2019-12-23 08:04:06

问题


Example. I've got an array with 15 objects. I want to start enumerating from a given index. Say start at index 5 and then the index above, the index under, above, under etc... I don't want it to wrap around, but rather stop and continue in unexplored direction.

So the order of indexes in my example would be. 5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0, 11, 12, 13, 14

How can this be done?


回答1:


Here's a more compact implementation that doesn't require creating subarrays:

@implementation NSArray (Extensions)

- (void)enumerateFromIndex:(NSUInteger)index goBothWaysUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block
{
    BOOL stop = NO;
    for (NSUInteger i = 0; i < self.count && !stop; i++) {
        if (index + i < self.count) {
            block([self objectAtIndex:index + i], index + i, &stop);
        }
        if (i != 0 && !stop && i <= index) {
            block([self objectAtIndex:index - i], index - i, &stop);
        }
    }
}

@end



回答2:


-(void)enumerateArray:(NSArray *)array inBothDirectionsFromIndex:(int)startIndex
{
    for (int i=0; i<array.count; i++)
    {
        int index = startIndex;
        int indexAfter = startIndex + round(i/2.f) + (i%2 ? 0 : 1);
        int indexBefore = startIndex - round(i/2.f);

        if ((i%2 && indexAfter < array.count) || indexBefore < 0)
        {
            index = indexAfter;
            if (indexBefore < 0)
                index -= indexBefore + 1;
        }
        else if ((i > 0 && indexBefore > -1) || indexAfter > array.count-1)
        {
            index = indexBefore;
            if (indexAfter > array.count-1)
                index -= indexAfter - array.count;;
        }

        id item = [array objectAtIndex:index];

        //Do what you want with the item here

    }
}



回答3:


It answers the question, but is not especially DRY and creating subarrays makes it less efficient than what it should be.

@implementation NSArray (Extensions)

- (void)enumerateFromIndex:(NSUInteger)index goBothWaysUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block
{
    NSArray *lastObjects = [self subarrayFromIndex:index];
    NSArray *firstObjects = [self subarrayToIndex:index];
    int currentIndex = 0;

    NSEnumerator *firstObjectsEnumerator = [firstObjects reverseObjectEnumerator];
    NSEnumerator *lastObjectsEnumerator = [lastObjects objectEnumerator];
    BOOL shouldStop = NO;
    NSUInteger numberOfIndexesEnumerated = 0;
    id obj = nil;

    while(numberOfIndexesEnumerated < self.count)
    {
        if (obj = [lastObjectsEnumerator nextObject])
        {
            NSInteger objIndex = [self indexOfObject:obj];
            block(obj, objIndex, &shouldStop);
            currentIndex++;
            numberOfIndexesEnumerated++;
        }
        if (shouldStop)
        {
            return;
        }

        if (obj = [firstObjectsEnumerator nextObject])
        {
            NSInteger objIndex = [self indexOfObject:obj];
            block(obj, objIndex, &shouldStop);
            currentIndex++;
            numberOfIndexesEnumerated++;
        }
        if (shouldStop)
        {
            return;
        }
    }
}

@end

Credits to @jalmaas for this answer



来源:https://stackoverflow.com/questions/14341488/enumerate-nsarray-starting-at-givven-index-searching-both-ways-no-wrap-around

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!