Cocoa / Objective-C - 如何逐步执行数组?

时间:2011-10-11 17:04:47

标签: objective-c arrays cocoa loops

不确定我是否正确写这个,但我需要做的是按顺序迭代一个数组但是通过2或3或4个索引。

所以你可以像这样迭代一个数组

for(id arrayObject in NSArray) { 
    //do something amazing with arrayObject
}

将按顺序迭代每个索引对象,[NSArray objectAtIndex:0],[NSArray objectAtIndex:1]等。

所以如果我只想要对象0,4,8,12等

由于

4 个答案:

答案 0 :(得分:6)

不完全。你编写它的方式,你省略了arrayObject的类,你正在迭代NSArray类名而不是实例。因此:

for (id arrayObject in myArray) {
    // do stuff with arrayObject
}

其中myArray的类型为NSArrayNSMutableArray

例如,NSString s

的数组
for (NSString *arrayObject in myArray) { /* ... */ }

如果要跳过阵列的某些部分,则必须使用计数器。

for (int i=0; i< [myArray count]; i+=4) {
    id arrayObject = [myArray objectAtIndex:i]; 
    // do something with arrayObject
}

答案 1 :(得分:4)

您可以使用enumerateObjectsUsingBlock:并检查块内的索引:

[myArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if( 0 == idx % 3 ){
        // Do work
    }
    else{
        // Continue enumeration
        return;
    }
}];

这也允许你根据某些原因操作基于非基于步幅的数组选择,例如if( (0 == idx % 3) || (0 == idx % 5) ),这对于普通的for循环来说会困难得多

答案 2 :(得分:3)

我想补充说,还有一些基于块的枚举方法,你可以使用。

NSMutableArray *evenArray = [NSMutableArray array];
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if (idx % 4 == 0) 
        [evenArray addObject:obj];
}];

现在evenArray将包含原始数组中索引为0,4,8,...的对象。

但是通常会想要在原始数组中只包含过滤后的对象,并且不需要额外的可变数组。

我写了一些基于块的方便的方法来实现这个目的:

array = [array arrayByPerformingBlock:^id(id element) {
    return element;
} ifElementPassesTest:^BOOL(id element) {
    return [array indexOfObject:element]%4 == 0;
}];

这将产生相同的结果,但隐藏了创建和填充可变数组的样板代码。

你会找到我的arraytools on GitHub

答案 3 :(得分:2)

您可以使用NSEnumerator执行此操作:

NSEnumerator *arrayEnum = [myArray objectEnumerator]; //Or reverseObjectEnumerator
for (MyThingy *thingy in arrayEnum) {
    doThingyWithThingy(thingy);

    [arrayEnum nextObject]; //Skip element
}

您可以在任何一点获得零个或多个nextObject条消息。对于每个第三个对象,在循环结束时你将有两个nextObject

for (MyThingy *thingy in arrayEnum) {
    doThingyWithThingy(thingy);

    //Skip two elements
    [arrayEnum nextObject];
    [arrayEnum nextObject];
}

基本上,这与通过循环一次收集多个对象的方式相同,只是没有实际使用其他对象。

在循环之前,您还可以拥有零个或多个nextObject消息,以便在您想要的第一个对象之前跳过一些对象。

(我希望你对你读过的数组做这个,而不是你自己生成的数组。后一种情况是你应该考虑从数组操作转移到模型对象的标志。)