Reputation: 2139
I want to get the index of the current object when using fast enumeration, i.e.
for (MyClass *entry in savedArray) {
// What is the index of |entry| in |savedArray|?
}
Upvotes: 29
Views: 12671
Reputation: 17902
I just had a pretty bad bug because I was doing this the way everyone else in here has suggested. That is, "create an index variable and increment it at the end of your loop".
I propose that this should be avoided and instead the following pattern should be followed:
int index = -1;
for (a in b) {
index++;
//Do stuff with `a`
}
The reason I recommend this odd pattern, is because if you use the continue;
feature of fast enumeration, it will skip the final index++
line of code at the end of your loop, and your index count will be off! For this reason I recommend starting at -1 and incrementing before doing anything else.
As for people who said just use indexOfObject:
this won't work with duplicate entries.
Upvotes: 0
Reputation: 15599
If you want to access the index or return outside block here is a piece of code that can be useful. (considering the array is an array of NSString).
- (NSInteger) findElemenent:(NSString *)key inArray:(NSArray *)array
{
__block NSInteger index = -1;
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isEqualToString:key]) {
*stop = YES;
index = idx;
}
}];
return index;
}
Upvotes: 3
Reputation: 9
A simple observation: If you initialize the index to -1 and then put the ++index as the first line in the for loop, doesn't that cover all bases (provided someone doesn't slip code in front of the increment)?
Upvotes: 0
Reputation: 1408
This question has already been answered, but I thought I would add that counting iterations is actually the technique mentioned in the iOS Developer Library documentation:
NSArray *array = <#Get an array#>;
NSUInteger index = 0;
for (id element in array) {
NSLog(@"Element at index %u is: %@", index, element);
index++;
}
I was sure there would be a fancy trick, but I guess not. :)
Upvotes: 7
Reputation: 38728
Look at the API for NSArray and you will see the method
- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block
So give that one a try
[savedArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
//... Do your usual stuff here
obj // This is the current object
idx // This is the index of the current object
stop // Set this to true if you want to stop
}];
Upvotes: 65
Reputation: 1686
I suppose the most blunt solution to this would be to simply increment an index manually.
NSUInteger indexInSavedArray = 0;
for (MyClass *entry in savedArray) {
indexInSavedArray++;
}
Alternatively, you could just not use fast enumeration.
for (NSUInteger indexInSavedArray = 0; indexInSavedArray < savedArray.count; indexInSavedArray++) {
[savedArray objectAtIndex:indexInSavedArray];
}
Upvotes: 9