简体   繁体   English

Cocoa / Objective-C-如何逐步遍历数组?

[英]Cocoa/Objective-C - How do I step through an array?

Not sure if I am wording this correctly but what I need to do is iterate through an array sequentially but by 2 or 3 or 4 indices. 不知道我的措词是否正确,但是我需要做的是依次遍历数组,但是要遍历2或3或4个索引。

So you can iterate through an array like this 这样您就可以遍历这样的数组

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

which will iterate sequentially through each indexed object, [NSArray objectAtIndex: 0], [NSArray objectAtIndex: 1], etc. 它将依次循环访问每个索引对象,[NSArray objectAtIndex:0],[NSArray objectAtIndex:1],依此类推。

so what if I just want object 0, 4, 8, 12, etc. 那如果我只想要对象0、4、8、12等呢?

Thanks 谢谢

Not quite. 不完全的。 The way you wrote it, you are omitting the class of the arrayObject , and you are iterating through the NSArray class name rather than an instance. 编写它的方式是,省略了arrayObject的类,并且遍历了NSArray类名而不是实例。 Thus: 从而:

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

where myArray is of type NSArray or NSMutableArray . 其中myArray的类型为NSArrayNSMutableArray

For instance, an array of NSString s 例如, NSString的数组

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

If you want to skip parts of the array, you will have to use a counter. 如果要跳过阵列的某些部分,则必须使用计数器。

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

You could use enumerateObjectsUsingBlock: and check the index inside the block: 您可以使用enumerateObjectsUsingBlock:并检查块内的索引:

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

This would also allow you to operate on non-stride-based selections of your array, if necessary for some reason, eg, if( (0 == idx % 3) || (0 == idx % 5) ) , which would be much more difficult with a plain for loop. 如果出于某些原因(例如, if( (0 == idx % 3) || (0 == idx % 5) ) ,则在必要时,这也将允许您对数组的基于非跨步的选择进行操作。使用普通的for循环要困难得多。

I'd like to add, that there are also block-based enumeration methods, you could use. 我想补充一点,您也可以使用基于块的枚举方法。

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

Now evenArray will contain the objects with the indexes 0,4,8,… in the original array. 现在, evenArray将在原始数组中包含索引为0、4、8,…的对象。

But often one will want to have just the filtered objects in the original array, and won't need a additionally mutable array. 但是通常人们只希望将经过过滤的对象包含在原始数组中,而不需要另外的可变数组。

I wrote some block-based convenient methods to achieve this: 我编写了一些基于块的便捷方法来实现此目的:

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

This will have the same result but hides the boilerplate code of creating and filling a mutable array. 这将具有相同的结果,但隐藏了创建和填充可变数组的样板代码。

You'll find my arraytools on GitHub . 您可以在GitHub上找到我的arraytools

You can do this with an NSEnumerator: 您可以使用NSEnumerator进行此操作:

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

    [arrayEnum nextObject]; //Skip element
}

You can have zero or more nextObject messages at either point. 您在任一点上都可以有零个或多个nextObject消息。 For every third object, you would have two nextObject s at the end of the loop: 对于每个第三个对象,循环末尾将有两个nextObject

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

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

Basically, this is the same way you gather multiple objects in a single pass through the loop, only without actually using the other objects. 基本上,这与您在循环中一次通过收集多个对象的方式相同,只是没有实际使用其他对象。

You can also have zero or more nextObject messages before the loop to skip some number of objects before the first one you want. 在循环之前,您还可以包含零个或多个nextObject消息,以在您想要的第一个对象之前跳过一些对象。

(I hope you're doing this to an array you read in, not one you generated yourself. The latter case is a sign that you should consider moving from array manipulation to model objects.) (我希望您对读入的数组执行此操作,而不是对自己生成的数组进行操作。后一种情况表明您应该考虑从数组操作转向模型对象。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM