2013-03-23 3 views
3

Каков наиболее сжатый способ итерации по индексам NSArray, которые происходят перед данным индексом? Например:Использование enumerateObjectsAtIndexes или for-loop для итерации по всем индексам NSArray ДО заданного индекса

NSArray *myArray = @[ @"animal" , @"vegetable" , @"mineral" , @"piano" ]; 

[myArray enumerateObjectsAtIndexes:@"all before index 2" options:nil 
    usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
      // this block will be peformed on @"animal" and @"vegetable" 
    }]; 

Кроме того, это не должно петля вообще, если данный показатель равен 0.

Что наиболее кратким, элегантный способ сделать это? До сих пор я только собрал неуклюжие многострочные ответы, которые используют раздражающие NSRanges и наборы индексов. Есть ли лучший способ, с которым я не обращаю внимания?

+0

любое количество способов реализации. Краткая информация не означает ясного. Используйте то, что хорошо работает. Не бороться с каркасом. Итерация NSArray не требует использования этого метода. Этот метод дает использование блоков, что отлично подходит для вещей, на которых хорошо. – uchuugaka

ответ

1

насчет:

index = 2; 
for (int i = 0; i < [myArray count] && i < index; ++i) { 
    id currObj = [myArray objectAtIndex:i]; 
    // Do your stuff on currObj; 
} 
+0

Почему 'i <[myArray count]' необходимо? – zakdances

+0

если index> = [myArray count] у вас проблемы :) – giorashc

3
NSArray *myArray = @[ @"animal" , @"vegetable" , @"mineral" , @"piano" ]; 
NSUInteger stopIndex = 2; 

[myArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
    if (idx == stopIndex) { 
     *stop = YES; // stop enumeration 
    } else { 
     // Do something ... 
     NSLog(@"%@", obj); 
    } 
}]; 
+0

Это хороший. Есть ли способ сделать это без if/else? Что-то вроде * stop = (idx == stopIndex)? (возврат;): НЕТ; – zakdances

+0

@yourfriendzak: Не совсем. Согласно документации, вы должны назначить 'YES'' 'stop'. И вызов 'return' из тернарного оператора - это то, что я бы назвал« запутывающим программированием »:-) –

+0

Это требование связано с параллельным перечислением, предлагаемым другим вариантом метода перечисления. – bbum

3
[myArray enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, idx)]  
          options:0 
         usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 

}]; 
+1

Почему '-1' в' NSMakeRange (-1, idx) '? Должно быть, это '0'? –

+0

@MartinR исправлено, спасибо – zakdances

+1

@yourfriendzak. также предоставляя nil в качестве аргумента для параметров (NSEnumerationOption): вы получите предупреждение о типе. Поэтому, вместо того, чтобы дать нуль здесь, лучше, если вы должны указать 0, если хотите проигнорировать предупреждение. – Arslan

1

Лично я бы с блочным перечислением, как показано на Martin R или yourfriendzak, принятый ответ на giorashc, вероятно, худший, как это не обеспечивает мутацию.

Я хочу добавить пример (правильный) Быстрая нумерация

NSUInteger stopIndex = 2; 
NSUInteger currentIndex = 0; 
for (MyClass *obj in objArray) { 
    if (currentIndex < stopIndex) { 
     // do sth... 
    } else { 
     break; 
    } 
    ++currentIndex;  
}