How can I reverse a NSArray in Objective-C? How can I reverse a NSArray in Objective-C? objective-c objective-c

How can I reverse a NSArray in Objective-C?


There is a much easier solution, if you take advantage of the built-in reverseObjectEnumerator method on NSArray, and the allObjects method of NSEnumerator:

NSArray* reversedArray = [[startArray reverseObjectEnumerator] allObjects];

allObjects is documented as returning an array with the objects that have not yet been traversed with nextObject, in order:

This array contains all the remaining objects of the enumerator in enumerated order.


For obtaining a reversed copy of an array, look at danielpunkass' solution using reverseObjectEnumerator.

For reversing a mutable array, you can add the following category to your code:

@implementation NSMutableArray (Reverse)- (void)reverse {    if ([self count] <= 1)        return;    NSUInteger i = 0;    NSUInteger j = [self count] - 1;    while (i < j) {        [self exchangeObjectAtIndex:i                  withObjectAtIndex:j];        i++;        j--;    }}@end


Some benchmarks

1. reverseObjectEnumerator allObjects

This is the fastest method:

NSArray *anArray = @[@"aa", @"ab", @"ac", @"ad", @"ae", @"af", @"ag",        @"ah", @"ai", @"aj", @"ak", @"al", @"am", @"an", @"ao", @"ap", @"aq", @"ar", @"as", @"at",        @"au", @"av", @"aw", @"ax", @"ay", @"az", @"ba", @"bb", @"bc", @"bd", @"bf", @"bg", @"bh",        @"bi", @"bj", @"bk", @"bl", @"bm", @"bn", @"bo", @"bp", @"bq", @"br", @"bs", @"bt", @"bu",        @"bv", @"bw", @"bx", @"by", @"bz", @"ca", @"cb", @"cc", @"cd", @"ce", @"cf", @"cg", @"ch",        @"ci", @"cj", @"ck", @"cl", @"cm", @"cn", @"co", @"cp", @"cq", @"cr", @"cs", @"ct", @"cu",        @"cv", @"cw", @"cx", @"cy", @"cz"];NSDate *methodStart = [NSDate date];NSArray *reversed = [[anArray reverseObjectEnumerator] allObjects];NSDate *methodFinish = [NSDate date];NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];NSLog(@"executionTime = %f", executionTime);

Result: executionTime = 0.000026

2. Iterating over an reverseObjectEnumerator

This is between 1.5x and 2.5x slower:

NSDate *methodStart = [NSDate date];NSMutableArray *array = [NSMutableArray arrayWithCapacity:[anArray count]];NSEnumerator *enumerator = [anArray reverseObjectEnumerator];for (id element in enumerator) {    [array addObject:element];}NSDate *methodFinish = [NSDate date];NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];NSLog(@"executionTime = %f", executionTime);

Result: executionTime = 0.000071

3. sortedArrayUsingComparator

This is between 30x and 40x slower (no surprises here):

NSDate *methodStart = [NSDate date];NSArray *reversed = [anArray sortedArrayUsingComparator: ^(id obj1, id obj2) {    return [anArray indexOfObject:obj1] < [anArray indexOfObject:obj2] ? NSOrderedDescending : NSOrderedAscending;}];NSDate *methodFinish = [NSDate date];NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];NSLog(@"executionTime = %f", executionTime);

Result: executionTime = 0.001100

So [[anArray reverseObjectEnumerator] allObjects] is the clear winner when it comes to speed and ease.