C# リストから要素を削除

C#

Remove, RemoveAt

リストから単純に要素を削除するには、Remove( )やRemoveAt()を使います。

C#
List<int> numbers = new List<int>();
numbers.AddRange(Enumerable.Range(0, 10).ToArray());
numbers.RemoveAt(2);
foreach (var item in numbers)
{
    Console.Write($"{item} ");
}
// 0 1 3 4 5 6 7 8 9 

List<string> members = ["John", "Jim", "Derek", "Bob"];
members.Remove("Jim");
foreach (var item in members)
    Console.Write($"{item} ");
// John Derek Bob   

RemoveAtはインデックスを指定してその要素を削除します。Removeは指定された要素を削除します。

基本的な使い方はとてもシンプルですが、注意点があります。次のコードはエラーになります。

C#
List<int> numbers = new List<int>();
numbers.AddRange(Enumerable.Range(0, 10).ToArray());
foreach (var item in numbers)
{
    if (item == 3)
    {
        numbers.Remove(item);
    }
    Console.WriteLine(item);
}
// Error: System.InvalidOperationException: Collection was modified; enumeration operation may not execute.

C# の foreach は内部で列挙子(IEnumerator)を使い、列挙中にコレクションが変更されると例外を投げる仕様になっています。
numbers.Remove(item) によって List の内部構造が書き換わり、列挙子の保持するバージョンと不整合が起きるため、次のような例外が発生します。

System.InvalidOperationException: “コレクションが変更されたため、列挙を完了できません。

特定条件に合う要素だけを削除する RemoveAll

RemoveAll( )を使うと、条件にあう要素を一気に削除することができます。

C#
List<int> numbers = new List<int>();
numbers.AddRange(Enumerable.Range(0, 10).ToArray());
numbers.RemoveAll(x => x > 5);
foreach (var item in numbers)
{
    Console.Write($"{item} ");
}
// 0 1 2 3 4 5 

この例では5番目以降の要素を全て削除しました。

C#
List<int> numbers = new List<int>();
numbers.AddRange(Enumerable.Range(0, 10).ToArray());
numbers.RemoveAll(x => x % 2 == 0);
foreach (var item in numbers)
{
    Console.Write($"{item} ");
}
// 1 3 5 7 9 

この例では偶数を全て削除しました。

このように条件をワンライナーで書ければ条件にあった要素を一括削除できます。

コメント

タイトルとURLをコピーしました