迭代时从NSMutableArray中移除的最佳方法是什么?

在Cocoa中,如果我想循环遍历一个NSMutableArray并删除符合特定条件的多个对象,那么每次删除一个对象时,如何在不重新启动循环的情况下执行此操作,最好的方法是什么?

谢谢,

编辑:只是为了澄清 - 我正在寻找最好的方式,例如比手动更新索引更优雅的东西。 例如在C ++中,我可以做;

iterator it = someList.begin();

while (it != someList.end())
{
    if (shouldRemove(it))   
        it = someList.erase(it);
}

为了清楚起见,我喜欢在收集要删除的项目时进行初始循环。 然后我删除它们。 以下是使用Objective-C 2.0语法的示例:

NSMutableArray *discardedItems = [NSMutableArray array];

for (SomeObjectClass *item in originalArrayOfItems) {
    if ([item shouldBeDiscarded])
        [discardedItems addObject:item];
}

[originalArrayOfItems removeObjectsInArray:discardedItems];

那么,索引是否正确更新,或其他小簿记细节是没有问题的。

编辑添加:

在其他答案中已经指出,逆配方应该更快。 即如果你遍历数组,并组成一个新的数组对象来保持,而不是丢弃对象。 这可能是真的(尽管分配新阵列的内存和处理成本以及丢弃旧阵列的成本如何?),但即使速度更快,它可能不会像原先的实现那么大,因为NSArrays不像“正常”阵列。 他们谈论这个谈话,但他们走了另一条路。 在这里看到一个好的分析:

逆配方可能会更快,但我从来不需要关心它是否是因为上述公式一直足以满足我的需求。

对我来说,回家的信息是使用任何最明确的表达方式。 只在必要时进行优化。 我个人认为上述表述最清楚,这就是我使用它的原因。 但是如果反面的表述对你更清楚,那就去做吧。


还有一个变种。 所以你得到可读性和良好的性能:

NSMutableIndexSet *discardedItems = [NSMutableIndexSet indexSet];
SomeObjectClass *item;
NSUInteger index = 0;

for (item in originalArrayOfItems) {
    if ([item shouldBeDiscarded])
        [discardedItems addIndex:index];
    index++;
}

[originalArrayOfItems removeObjectsAtIndexes:discardedItems];

其他一些答案在非常大的数组上的性能很差,因为像removeObject:removeObjectsInArray:这样的方法涉及到对接收器进行线性搜索,这很浪费,因为您已经知道对象在哪里。 此外,对removeObjectAtIndex:任何调用都必须removeObjectAtIndex:将索引中的值复制到阵列的末尾一个位置。

效率更高的是以下几点:

NSMutableArray *array = ...
NSMutableArray *itemsToKeep = [NSMutableArray arrayWithCapacity:[array count]];
for (id object in array) {
    if (! shouldRemove(object)) {
        [itemsToKeep addObject:object];
    }
}
[array setArray:itemsToKeep];

因为我们设置了itemsToKeep的容量, itemsToKeep我们不会浪费任何时间在调整大小时复制值。 我们不修改数组,所以我们可以自由使用快速枚举。 使用setArray:itemsToKeep替换array的内容将是高效的。 根据你的代码,你甚至可以用最后一行代替:

[array release];
array = [itemsToKeep retain];

所以甚至不需要复制值,只需交换一个指针。

链接地址: http://www.djcxy.com/p/85143.html

上一篇: Best way to remove from NSMutableArray while iterating?

下一篇: world problems with naive shuffling