2010-12-18 72 views
2

Objective-c通过'for(a in b)语法拥有一个内置列表迭代器,可以很好地与NSArray和其他集合一起工作。但是,它可以消除这样的迭代过程中项目,而不丑的技巧,比如在objective-c中迭代列表并从中删除项目?

for(int i = 0, i < [array count]; i ++) 
{ 
    if(condition) 
    { 
    [array removeItemAtIndex : i]; 
    i --; 
    } 
} 

回答

14

您可以按照相反的顺序遍历数组,所以你不会需要额外的调整指数:

for(int i = [array count]-1; i >=0; --i) 
{ 
    if(condition) 
    { 
     [array removeItemAtIndex : i]; 
    } 
} 

或者累积指标要删除索引集,而枚举,然后一次删除所有元素:

NSMutableIndexSet *indexes = [[NSMutableIndexSet alloc] init]; 
for(int i = 0, i < [array count]; i ++) 
{ 
    if(condition) 
    { 
    [indexes addIndex : i]; 
    } 
} 
[array removeObjectsAtIndexes:indexes]; 
[indexes release]; 

我会选择第二个选项,因为改变阵列,同时在列举可能不是一个好作风(虽然它不会给你在这个特定情况下的错误)

+0

我想你的第二个答案将是“官方”最好的方式来做到这一点。虽然你的第一个答案在我看来更好。他们都可能以同样的方式工作。 – Accatyyc 2010-12-18 22:52:59

+4

第二种方法可能(直观地)更高效,因为您一次删除元素,另外Ole Bergeman说,在枚举集合时更改集合通常不是一个好主意 - 如果您在“快速枚举”它时进行变异集合,则会发生错误。 – Vladimir 2010-12-18 22:57:12

+0

第一个答案中的for循环使用逗号而不是分号。没什么大不了的,但我只是复制了代码并看到了。谢谢。 – Hahnemann 2014-06-22 22:44:46

3

不,在明确禁止枚举它时突变集合。您可以将应该删除的对象添加到第二个临时可变数组中,然后在循环外部使用removeObjectsInArray:从原始数组中删除该数组中的对象。

+1

...在使用快速枚举*时被明确禁止*。当使用普通的'for()'循环时,这并不是一个好主意,但它是允许的。 – 2010-12-19 01:58:37

+0

@Dave:不仅仅是快速枚举。使用标准的NSEnumerators也是“不安全的”。因此,当我看到它时,突然改变一个集合,同时_enumerating_它确实被禁止,而在_iterating_的过程中可以这样做。 – 2010-12-19 12:40:28

+0

够公平的。 :) – 2010-12-19 19:08:23

2

我不会说它是一个肮脏的技巧,向后遍历数组。对于(int i = array.count-1; i> = 0; i--) if(condition) [array removeItemAtIndex:i];

1

如果我需要它,我复制我的阵列,并一一列举而另一个变异

NSArray *arr = firstArr; 
for(int i = [array count]-1, i >=0; --i) 
{ 
    if(condition) 
    { 
     [firstArr removeItemAtIndex : i]; 
    } 
} 

但我认为弗拉基米尔的例子就是最好的一个;)(只是把所有的可能性)