例子。我有一个包含 15 个对象的数组。我想从给定的索引开始枚举。说从索引 5 开始,然后是上面的索引,下面的索引,上面的索引,下面的等等……我不希望它环绕,而是停止并继续朝着未知的方向前进。
所以我的例子中的索引顺序是。5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0, 11, 12, 13, 14
如何才能做到这一点?
例子。我有一个包含 15 个对象的数组。我想从给定的索引开始枚举。说从索引 5 开始,然后是上面的索引,下面的索引,上面的索引,下面的等等……我不希望它环绕,而是停止并继续朝着未知的方向前进。
所以我的例子中的索引顺序是。5, 6, 4, 7, 3, 8, 2, 9, 1, 10, 0, 11, 12, 13, 14
如何才能做到这一点?
这是一个不需要创建子数组的更紧凑的实现:
@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
-(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
}
}
它回答了这个问题,但并不是特别干燥,并且创建子数组使其效率低于应有的效率。
@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
此答案归功于@jalmaas