Is there an easy way to iterate over an NSArray backwards?
Asked Answered
S

5

71

I've got an NSArray and have to iterate over it in a special case backwards, so that I first look at the last element. It's for performance reasons: If the last one just makes no sense, all previous ones can be ignored. So I'd like to break the loop. But that won't work if I iterate forward from 0 to n. I need to go from n to 0. Maybe there is a method or function I don't know about, so I wouldn't have to re-invent the wheel here.

Stanger answered 9/5, 2009 at 22:16 Comment(2)
"How can I reverse a NSArray in Objective-C?" is a completely different question.Contrition
Swift: #24509092Ferrin
F
199

To add on the other answers, you can use -[NSArray reverseObjectEnumerator] in combination with the fast enumeration feature in Objective-C 2.0 (available in Leopard, iPhone):

for (id someObject in [myArray reverseObjectEnumerator])
{
    // print some info
    NSLog([someObject description]);
}

Source with some more info: http://cocoawithlove.com/2008/05/fast-enumeration-clarifications.html

Fennell answered 10/5, 2009 at 0:16 Comment(4)
Is this considered fast enumeration, and is this faster than a regular c for loop that starts from [myArray count]-1? How do you iterate over an NSString backwards?Regenerator
I don’t have any links here right now but there is a video somewhere (could’ve been a WWDC) where an Apple engineer explains how fast enumeration works and why it is fast. It outperforms both index-based NSArray enumeration and classic Foundation enumerators and, depending on the scenario, by a lot.Fennell
I have to run a reverse for loop on a dictionary, how to do so?Bruin
@AshwinG Your question doesn't make sense, as NSDictionarys don't have an 'order'. You can enumerate them in any real order, unless you first order the keys/values.Tod
T
16

Since this is for performace, you have a number of options and would be well advised to try them all to see which works best.

  • [array enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:…]
  • -[NSArray reverseObjectEnumerator]
  • Create a reverse copy of the array and then iterate through that normally
  • Use a standard C for loop and start and work backwards through the array.

More extreme methods (if performance is super-critical)

  • Read up on how Cocoa implements fast object enumeration and create your own equivalent in reverse.
  • Use a C or C++ array.

There may be others. In which case, anyone feel free to add it.

Then answered 9/5, 2009 at 22:16 Comment(1)
I would say that the enumerateObjectsWithOptions:NSEnumerationReverse is the best answer, especially if you need to know what index you are on. Thanks!!!Somewhat
G
11

From here:

 NSEnumerator* myIterator = [myArray reverseObjectEnumerator];
 id anObject;

 while( anObject = [myIterator nextObject])
 {
     /* do something useful with anObject */
 }
Gentlewoman answered 9/5, 2009 at 22:24 Comment(0)
B
2
for (int i = ((int)[array count] - 1); i > -1; i--) {
    NSLog(@"element: %@",array[i]);
}
Bleeder answered 5/3, 2018 at 8:3 Comment(1)
This does not detect changes to a mutable array instance during enumeration (elements, count). Otherwise probably a little faster than creating an NSEnumerator object.Coxswain
B
1
[NsArray reverseObjectEnumerator]
Brendabrendan answered 9/5, 2009 at 22:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.