1. ホーム
  2. objective-c

[解決済み】NSMutableArrayから反復処理中に削除する最良の方法は?

2022-04-15 04:48:06

質問

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];

そうすれば、インデックスが正しく更新されているかどうかなど、細かな帳簿上の疑問はなくなります。

追記編集しました。

他の回答で、逆形式の方が高速であることが指摘されています。つまり、配列を繰り返し処理し、破棄するオブジェクトの代わりに、保持するオブジェクトの新しい配列を構成する場合です。 しかし、NSArray は通常の配列のようには動作しないので、たとえ速くなったとしても、素朴な実装ではそれほど大きな問題にはならないかもしれません。 NSArray は通常の配列のように動作しないからです。 良い分析はこちらをご覧ください。

逆計算の方が速いかもしれませんが、私の場合は上記の計算で十分速いので、逆計算を気にする必要はありません。

私にとって重要なメッセージは、自分にとって最も分かりやすい方式を使うことです。 必要な場合のみ最適化する。 私自身は、上記の方式が一番わかりやすいと思うので、それを使っています。 しかし、もし逆計算の方がわかりやすいのであれば、そちらを使ってください。