我需要反转NSArray。

举个例子:

[1,2,3,4,5]必须变成:[5,4,3,2,1]

实现这一目标的最佳方式是什么?


当前回答

我不知道有什么内置方法。 但是,手工编码并不太难。假设你正在处理的数组元素是整数类型的NSNumber对象,'arr'是你想反转的NSMutableArray。

int n = [arr count];
for (int i=0; i<n/2; ++i) {
  id c  = [[arr objectAtIndex:i] retain];
  [arr replaceObjectAtIndex:i withObject:[arr objectAtIndex:n-i-1]];
  [arr replaceObjectAtIndex:n-i-1 withObject:c];
}

因为你从一个NSArray开始,那么你必须先用原始NSArray ('origArray')的内容创建可变数组。

NSMutableArray * arr = [[NSMutableArray alloc] init];
[arr setArray:origArray];

编辑:修正了循环计数中的n -> n/2,并根据布伦特的回答中的建议将NSNumber更改为更通用的id。

其他回答

有一个更简单的解决方案,如果你利用NSArray内置的reverseObjectEnumerator方法,以及NSEnumerator的allObjects方法:

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

allObjects被记录为返回一个数组,其中的对象还没有被nextObject遍历,顺序如下:

该数组按枚举顺序包含枚举器的所有剩余对象。

在看了上面其他人的答案并在这里找到马特·加拉格尔的讨论后

我建议:

NSMutableArray * reverseArray = [NSMutableArray arrayWithCapacity:[myArray count]]; 

for (id element in [myArray reverseObjectEnumerator]) {
    [reverseArray addObject:element];
}

正如Matt所观察到的:

在上面的例子中,你可能想知道-[NSArray reverseObjectEnumerator]是否会在循环的每次迭代中运行-可能会降低代码的速度。<…>

此后不久,他这样回答:

<……当for循环开始时,"collection"表达式只计算一次。这是最好的情况,因为您可以安全地将昂贵的函数放在“collection”表达式中,而不会影响循环的每次迭代性能。

反向枚举数组的最有效方法:

使用enumerateObjectsWithOptions:NSEnumerationReverse usingBlock。使用@JohannesFahrenkrug上面的基准测试,这比[[array reverseObjectEnumerator] allObjects]快8倍;:

NSDate *methodStart = [NSDate date];

[anArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    //
}];

NSDate *methodFinish = [NSDate date];
NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
NSLog(@"executionTime = %f", executionTime);

要获得数组的反向副本,请参阅danielpunkass使用reverseObjectEnumerator的解决方案。

为了反转一个可变数组,你可以在你的代码中添加以下类别:

@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

有一个简单的方法。

    NSArray *myArray = @[@"5",@"4",@"3",@"2",@"1"];
    NSMutableArray *myNewArray = [[NSMutableArray alloc] init]; //this object is going to be your new array with inverse order.
    for(int i=0; i<[myNewArray count]; i++){
        [myNewArray insertObject:[myNewArray objectAtIndex:i] atIndex:0];
    }
    //other way to do it
    for(NSString *eachValue in myArray){
        [myNewArray insertObject:eachValue atIndex:0];
    }

    //in both cases your new array will look like this
    NSLog(@"myNewArray: %@", myNewArray);
    //[@"1",@"2",@"3",@"4",@"5"]

我希望这能有所帮助。