C#のListでRemoveとRemoveAtはどう使い分ける?ゲーム開発で考えてみよう

広告

C#のList<T>には、要素を削除するためのメソッドとしてRemoveRemoveAtがあります。

名前が似ているため、「何が違うの?」「どちらを使えばいいの?」と迷いやすいところです。

結論から言うと、次のように覚えると分かりやすいです。

Remove = 「何を消す?」
RemoveAt = 「何番目を消す?」

Removeは対象の敵を削除し、RemoveAtはインデックス2のアイテムを削除して後ろを詰める違いを示す図

Removeは「このデータを消したい」とき

たとえば、ゲーム内に敵の一覧があるとします。

List<Enemy> enemies = new List<Enemy>();

倒された敵を削除したい場合は、次のように書けます。

enemies.Remove(enemy);

これは、「このenemyを一覧から削除してください」という意味です。

  • この敵を消す
  • このアイテムを消す
  • この弾を消す
  • このキャラクターを一覧から外す

ゲームでは削除したい対象がすでに分かっていることが多いため、Removeはとても自然に使えます。

RemoveAtは「何番目を消す」とき

一方、RemoveAtはインデックスを指定して削除します。

enemies.RemoveAt(3);

これは「インデックス3の要素を削除する」という意味です。インデックスは0から始まるため、実際には「4番目の敵」を削除しています。

ゲームではどう使い分ける?

場面向いているメソッド
この敵を削除したいRemove
このアイテムを削除したいRemove
この弾を削除したいRemove
選択中のスロットを削除したいRemoveAt
手札の3枚目を削除したいRemoveAt
インデックスで調べながら削除したいRemoveAt

対象そのものが分かっているならRemove、位置が分かっているならRemoveAtと考えるとよいでしょう。

たとえば手札ならRemoveAtが分かりやすい

カードゲームで、次のような手札があるとします。

List<string> cards = new List<string>
{
    "剣",
    "盾",
    "魔法",
    "回復"
};

「3枚目のカードを捨てる」という処理なら、次のように書けます。

cards.RemoveAt(2);

このように、「何番目を選択したか」が重要なUIでは、RemoveAtが使いやすくなります。

RemoveAtを使うと後ろの要素が詰まる

ここは重要です。次のListがあるとします。

0: 剣
1: 盾
2: 魔法
3: 回復

このListに対してcards.RemoveAt(1);を実行すると、「盾」が削除されます。その後は次のようになります。

0: 剣
1: 魔法
2: 回復

削除された場所は空いたままにはならず、後ろの要素が前に詰まります。配列との違いを理解するうえでも重要なポイントです。

ループ中のRemoveAtには注意

RemoveAtをループの中で使う場合は、少し注意が必要です。たとえば、HPが0以下の敵を削除する場合です。

for (int i = enemies.Count - 1; i >= 0; i--)
{
    if (enemies[i].HP <= 0)
    {
        enemies.RemoveAt(i);
    }
}

後ろから調べているのがポイントです。要素を削除するとインデックスがずれるため、前から削除すると要素を飛ばしてしまうことがあります。

どちらをよく使う?

ゲーム開発では、RemoveAtよりRemoveの方が自然な場面は多めです。「4番目の敵を消したい」というより、「この倒された敵を消したい」という処理の方が多いからです。

ただし、インベントリや手札、メニューなど、「何番目を選択したか」が重要な場面ではRemoveAtが非常に便利です。

まとめ

Remove = 「何を消す?」

enemies.Remove(enemy);

RemoveAt = 「何番目を消す?」

enemies.RemoveAt(3);

どちらが優れているということではなく、削除したいものを「対象」で指定するのか、「位置」で指定するのかの違いです。

ゲーム開発では、「この敵を消す」ならRemove、「選択された3番目を消す」ならRemoveAtと考えると、使い分けやすくなります。

訪問数 5 回, 今日の訪問数 5回

広告