C# DictionaryのRemoveで要素を削除する方法|キー指定・全削除も解説
はじめに
C#でキーと値のペアを扱うときによく使われるのがDictionary<TKey, TValue>です。ユーザーIDに対するユーザー名、商品コードに対する商品情報、設定名に対する設定値など、キーを使って値を高速に取り出したい場面で便利です。
一方で、登録したデータが不要になったときは、Dictionaryから要素を削除する必要があります。そのときによく使うのがRemoveメソッドです。
この記事では、C#のDictionaryでRemoveを使って要素を削除する基本から、キー指定での削除、全削除、条件に一致する要素の削除、よくあるエラーや実践的な書き方まで解説します。
1. C#のDictionaryで要素を削除する基本
1-1. Dictionaryとは何か
Dictionary<TKey, TValue>は、キーと値をセットで管理するコレクションです。キーを指定すると、それに対応する値を取得できます。
たとえば、次のように文字列のキーに対して整数の値を持つDictionaryを作成できます。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("Alice", 90);
scores.Add("Bob", 75);
scores.Add("Charlie", 82);
この例では、"Alice"、"Bob"、"Charlie"がキーで、90、75、82が値です。
Dictionaryでは、キーは重複できません。同じキーを追加しようとするとエラーになります。そのため、キーを使って特定の要素を一意に管理したい場合に向いています。
1-2. Dictionaryから要素を削除する主な方法
C#のDictionaryから要素を削除する方法には、主に次のようなものがあります。
C#dictionary.Remove(key);
dictionary.Clear();
Removeは、指定したキーに対応する1件の要素を削除します。
一方、ClearはDictionary内のすべての要素を削除します。
つまり、特定のキーだけ削除したい場合はRemove、Dictionaryを空にしたい場合はClearを使います。
1-3. Removeメソッドでできること
Removeメソッドを使うと、指定したキーに対応する要素をDictionaryから削除できます。
C#scores.Remove("Bob");
このコードを実行すると、キーが"Bob"の要素がDictionaryから削除されます。
削除後のDictionaryには、"Alice"と"Charlie"だけが残ります。
C#foreach (var score in scores)
{
Console.WriteLine($"{score.Key}: {score.Value}");
}
出力例は次のようになります。
C#Alice: 90
Charlie: 82
1-4. Removeを使う場面
Removeは、特定のデータだけをDictionaryから取り除きたいときに使います。
たとえば、次のような場面です。
C#// ログアウトしたユーザーのセッション情報を削除する
sessions.Remove(userId);
// 販売終了した商品の情報を削除する
products.Remove(productId);
// キャッシュから不要になったデータを削除する
cache.Remove(cacheKey);
Dictionaryはキーを使ってデータを管理するため、削除時も基本的にはキーを指定します。値を直接指定して削除するのではなく、キーを指定して削除する点を理解しておくと、Dictionaryの削除処理が書きやすくなります。
2. DictionaryのRemoveでキーを指定して要素を削除する方法
2-1. Removeメソッドの基本構文
DictionaryのRemoveメソッドの基本構文は次のとおりです。
C#dictionary.Remove(key);
たとえば、キーの型がstring、値の型がintのDictionaryであれば、次のように書きます。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("Alice", 90);
scores.Add("Bob", 75);
scores.Remove("Bob");
Removeには、削除したい要素のキーを渡します。値ではなくキーを指定する点に注意してください。
2-2. キーを指定して1件削除するサンプルコード
次のコードでは、Dictionaryからキー"banana"の要素を削除しています。
C#Dictionary<string, int> prices = new Dictionary<string, int>
{
{ "apple", 120 },
{ "banana", 80 },
{ "orange", 100 }
};
prices.Remove("banana");
foreach (var item in prices)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
出力結果は次のようになります。
C#apple: 120
orange: 100
"banana"に対応する要素が削除されていることがわかります。
2-3. Removeの戻り値で削除できたか判定する
Removeメソッドは、削除に成功したかどうかをboolで返します。
キーが存在して削除できた場合はtrue、キーが存在しなかった場合はfalseです。
C#Dictionary<string, int> prices = new Dictionary<string, int>
{
{ "apple", 120 },
{ "banana", 80 },
{ "orange", 100 }
};
bool removed = prices.Remove("banana");
if (removed)
{
Console.WriteLine("削除しました。");
}
else
{
Console.WriteLine("指定したキーは存在しません。");
}
出力結果は次のようになります。
C#削除しました。
このように、Removeの戻り値を使えば、削除できた場合とできなかった場合で処理を分けられます。
2-4. 存在しないキーを指定した場合の動作
DictionaryのRemoveで存在しないキーを指定しても、例外は発生しません。
C#Dictionary<string, int> prices = new Dictionary<string, int>
{
{ "apple", 120 },
{ "banana", 80 }
};
bool removed = prices.Remove("orange");
Console.WriteLine(removed);
出力結果は次のようになります。
C#False
キー"orange"はDictionary内に存在しないため、削除は行われず、戻り値はfalseになります。
そのため、単に「存在すれば削除する」という処理であれば、事前にContainsKeyで確認しなくても問題ありません。
C#prices.Remove("orange");
このように書いても、存在しないキーを指定しただけでエラーになることはありません。
3. Dictionaryの要素をすべて削除する方法
3-1. Clearメソッドで全削除する
Dictionaryの要素をすべて削除したい場合は、RemoveではなくClearメソッドを使います。
C#Dictionary<string, int> prices = new Dictionary<string, int>
{
{ "apple", 120 },
{ "banana", 80 },
{ "orange", 100 }
};
prices.Clear();
Console.WriteLine(prices.Count);
出力結果は次のようになります。
C#0
Clearを実行すると、Dictionary内のすべての要素が削除されます。
3-2. RemoveとClearの違い
RemoveとClearの違いは、削除対象の範囲です。
Removeは、指定したキーに対応する1件の要素を削除します。
C#prices.Remove("apple");
一方、ClearはDictionary内の要素をすべて削除します。
C#prices.Clear();
特定のキーだけ削除したい場合はRemove、Dictionaryを空にしたい場合はClearを使うと覚えておくとよいでしょう。
3-3. 全削除後のCountの確認方法
Dictionaryに現在いくつの要素が入っているかは、Countプロパティで確認できます。
C#Dictionary<string, int> prices = new Dictionary<string, int>
{
{ "apple", 120 },
{ "banana", 80 },
{ "orange", 100 }
};
Console.WriteLine(prices.Count);
prices.Clear();
Console.WriteLine(prices.Count);
出力結果は次のようになります。
C#3
0
Clearを実行する前は3件、実行後は0件になっています。
削除処理の結果を確認したい場合は、Countを使うとわかりやすくなります。
3-4. Dictionary自体をnullにする方法との違い
Dictionaryの要素をすべて削除する方法として、次のように変数にnullを代入するコードを見かけることがあります。
C#prices = null;
これはDictionaryの中身を空にしているのではなく、変数がDictionaryのインスタンスを参照しない状態にしているだけです。
そのため、nullにしたあとにDictionaryを使おうとすると、NullReferenceExceptionが発生します。
C#prices = null;
// NullReferenceExceptionが発生する
Console.WriteLine(prices.Count);
一方、Clearを使った場合はDictionaryのインスタンス自体は残ります。
C#prices.Clear();
Console.WriteLine(prices.Count);
この場合、Countは0になり、Dictionaryは空の状態で引き続き使えます。
Dictionaryを再利用したい場合はClear、Dictionaryそのものが不要になった場合は参照を外す、というように使い分けるとよいでしょう。
4. 条件に一致する要素を削除する方法
4-1. 値を条件にして削除する考え方
DictionaryのRemoveはキーを指定して要素を削除するメソッドです。そのため、値を条件にして削除したい場合でも、最終的には削除対象のキーを取得してからRemoveを呼び出します。
たとえば、「価格が100円未満の商品を削除したい」という場合、次の流れになります。
C#// 1. 条件に一致する要素のキーを取得する
// 2. 取得したキーを使ってRemoveする
Dictionaryから値を直接指定して削除する専用メソッドはありません。条件削除では、削除対象のキーを先に集めるのが基本です。
4-2. Whereで削除対象のキーを取得する
LINQのWhereを使うと、条件に一致する要素を抽出できます。
C#var keysToRemove = prices
.Where(x => x.Value < 100)
.Select(x => x.Key)
.ToList();
このコードでは、値が100未満の要素を探し、そのキーだけをリストにしています。
x.KeyはDictionaryのキー、x.ValueはDictionaryの値を表します。
4-3. foreach中にRemoveするときの注意点
Dictionaryをforeachで列挙している途中に、そのDictionaryに対してRemoveを実行すると、InvalidOperationExceptionが発生することがあります。
たとえば、次のようなコードは避けるべきです。
C#foreach (var item in prices)
{
if (item.Value < 100)
{
prices.Remove(item.Key);
}
}
Dictionaryを列挙している最中にコレクションの内容を変更しているため、エラーの原因になります。
安全に削除するには、削除対象のキーを先に別のリストにしてから、そのリストを使って削除します。
4-4. ToListを使って安全に削除するサンプルコード
条件に一致する要素を安全に削除するには、ToListを使って削除対象のキーを先に確定させます。
C#Dictionary<string, int> prices = new Dictionary<string, int>
{
{ "apple", 120 },
{ "banana", 80 },
{ "orange", 100 },
{ "grape", 90 }
};
var keysToRemove = prices
.Where(x => x.Value < 100)
.Select(x => x.Key)
.ToList();
foreach (var key in keysToRemove)
{
prices.Remove(key);
}
foreach (var item in prices)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
出力結果は次のようになります。
C#apple: 120
orange: 100
"banana"と"grape"は値が100未満なので削除されています。
ポイントは、Dictionaryを直接列挙しながら削除しないことです。先に削除対象のキー一覧を作ってから、そのキー一覧に対してforeachを行えば安全に削除できます。
5. DictionaryのRemoveでよくあるエラーと注意点
5-1. foreach中に削除してInvalidOperationExceptionが起きる原因
Dictionaryをforeachで回している途中にRemoveを呼び出すと、次のような例外が発生することがあります。
C#System.InvalidOperationException
これは、列挙中のコレクションが変更されたためです。
たとえば、次のコードは問題があります。
C#foreach (var item in prices)
{
if (item.Value < 100)
{
prices.Remove(item.Key);
}
}
foreachはDictionaryの状態を前提に順番に要素を取り出しています。その途中でDictionaryの要素数が変わると、列挙処理を続けられなくなるため、例外が発生します。
この問題を避けるには、次のように削除対象のキーを先にリスト化します。
C#var keysToRemove = prices
.Where(x => x.Value < 100)
.Select(x => x.Key)
.ToList();
foreach (var key in keysToRemove)
{
prices.Remove(key);
}
条件削除では、この書き方を基本として覚えておくと安全です。
5-2. 存在確認にContainsKeyは必要か
Dictionaryからキーを指定して削除する場合、事前にContainsKeyで存在確認をするコードもあります。
C#if (prices.ContainsKey("apple"))
{
prices.Remove("apple");
}
この書き方でも問題ありませんが、削除できたかどうかを知りたいだけなら、Removeの戻り値を使うほうが簡潔です。
C#if (prices.Remove("apple"))
{
Console.WriteLine("削除しました。");
}
else
{
Console.WriteLine("キーが存在しません。");
}
Removeは、キーが存在しない場合でも例外を投げずにfalseを返します。そのため、多くの場合はContainsKeyを先に呼ばなくても十分です。
ただし、削除前にキーの存在を使って別の処理をしたい場合は、ContainsKeyを使っても問題ありません。
5-3. nullキーやnull値を扱う場合の注意点
Dictionaryでnullを扱う場合は、キーと値を分けて考える必要があります。
まず、参照型の値にはnullを入れられます。
C#Dictionary<string, string?> users = new Dictionary<string, string?>
{
{ "001", "Alice" },
{ "002", null }
};
この場合、キー"002"に対応する値はnullです。値がnullであっても、キーを指定すれば削除できます。
C#users.Remove("002");
一方、キーにnullを使うことはできません。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
// ArgumentNullExceptionが発生する
scores.Remove(null);
キーの型がstringなどの参照型であっても、Dictionaryのキーとしてnullを指定することはできません。削除処理でキーがnullになる可能性がある場合は、事前にチェックしておくと安全です。
C#string? key = GetKey();
if (key != null)
{
scores.Remove(key);
}
5-4. 削除後にDictionaryの件数を確認する方法
削除後にDictionaryの件数を確認したい場合は、Countプロパティを使います。
C#Dictionary<string, int> scores = new Dictionary<string, int>
{
{ "Alice", 90 },
{ "Bob", 75 },
{ "Charlie", 82 }
};
scores.Remove("Bob");
Console.WriteLine(scores.Count);
出力結果は次のようになります。
C#2
Removeで1件削除されたため、件数は2件になります。
削除できたかどうかを確認したい場合はRemoveの戻り値、削除後の件数を確認したい場合はCountを使うとよいでしょう。
6. Removeメソッドの実践的な使い方
6-1. キャッシュから不要なデータを削除する
Dictionaryは、簡易的なキャッシュとして使われることがあります。たとえば、商品IDをキーにして商品名を一時的に保持するケースです。
C#Dictionary<int, string> productCache = new Dictionary<int, string>
{
{ 1, "ノートPC" },
{ 2, "マウス" },
{ 3, "キーボード" }
};
int productId = 2;
productCache.Remove(productId);
このコードでは、商品ID2のキャッシュを削除しています。
削除できたかどうかをログに残したい場合は、戻り値を使います。
C#if (productCache.Remove(productId))
{
Console.WriteLine("キャッシュを削除しました。");
}
else
{
Console.WriteLine("キャッシュは存在しませんでした。");
}
6-2. ユーザーIDや商品IDをキーにして削除する
Dictionaryでは、ユーザーIDや商品IDのような一意の値をキーにすることがよくあります。
C#Dictionary<int, string> users = new Dictionary<int, string>
{
{ 101, "Alice" },
{ 102, "Bob" },
{ 103, "Charlie" }
};
int userId = 102;
users.Remove(userId);
このコードでは、ユーザーID102のユーザーを削除しています。
IDをキーにしておくと、削除対象を明確に指定できます。
C#bool removed = users.Remove(userId);
Console.WriteLine(removed ? "ユーザーを削除しました。" : "ユーザーが見つかりません。");
業務アプリケーションでも、商品ID、注文ID、会員IDなどをキーにしてDictionaryを扱うケースは多くあります。
6-3. 重複チェック用Dictionaryから要素を削除する
Dictionaryは、重複チェックにも利用できます。
たとえば、すでに処理したメールアドレスをDictionaryで管理する場合を考えます。
C#Dictionary<string, bool> processedEmails = new Dictionary<string, bool>
{
{ "alice@example.com", true },
{ "bob@example.com", true }
};
string email = "bob@example.com";
processedEmails.Remove(email);
このコードでは、"bob@example.com"を処理済みリストから削除しています。
再処理を許可したい場合や、対象外になったデータを管理対象から外したい場合に使えます。
なお、値を使わずキーの存在だけを管理したい場合は、HashSet<T>の利用も検討できます。ただし、キーに対して何らかの値も持たせたい場合はDictionaryが便利です。
6-4. TryGetValueと組み合わせて削除前に値を取得する
削除する前に、削除対象の値を確認したい場合はTryGetValueと組み合わせます。
C#Dictionary<int, string> users = new Dictionary<int, string>
{
{ 101, "Alice" },
{ 102, "Bob" },
{ 103, "Charlie" }
};
int userId = 102;
if (users.TryGetValue(userId, out string? userName))
{
users.Remove(userId);
Console.WriteLine($"{userName}を削除しました。");
}
else
{
Console.WriteLine("ユーザーが見つかりません。");
}
出力結果は次のようになります。
C#Bobを削除しました。
この書き方は、削除前の値をログに残したい場合や、削除対象の情報を画面に表示したい場合に便利です。
また、C#のバージョンや対象フレームワークによっては、削除と同時に値を取得できるRemove(key, out value)形式も利用できます。
C#if (users.Remove(userId, out string? removedUserName))
{
Console.WriteLine($"{removedUserName}を削除しました。");
}
else
{
Console.WriteLine("ユーザーが見つかりません。");
}
この形式を使うと、値の取得と削除をまとめて書けるため、コードを簡潔にできます。
7. Dictionaryの削除処理をわかりやすく書くコツ
7-1. 削除対象のキー名を明確にする
DictionaryのRemoveではキーを指定して削除するため、削除対象のキーが何を表しているのかをわかりやすくすることが大切です。
たとえば、次のような変数名では意味が少し曖昧です。
C#int id = 102;
users.Remove(id);
ユーザーIDを表すなら、次のように書くほうが読みやすくなります。
C#int userId = 102;
users.Remove(userId);
商品IDであればproductId、注文IDであればorderIdのように、キーの意味がわかる名前にすると、削除処理の意図が明確になります。
7-2. Removeの戻り値を活用して分岐を書く
Removeの戻り値を使うと、削除できた場合とできなかった場合で処理を分けられます。
C#if (users.Remove(userId))
{
Console.WriteLine("ユーザーを削除しました。");
}
else
{
Console.WriteLine("指定されたユーザーは存在しません。");
}
この書き方にすると、ContainsKeyで事前確認してからRemoveするよりも簡潔です。
C#if (users.ContainsKey(userId))
{
users.Remove(userId);
}
もちろん、削除前に値を確認したい場合や、存在する場合だけ別の処理をしたい場合はContainsKeyやTryGetValueを使っても構いません。
ただ、単純に削除できたかを判定したいだけなら、Removeの戻り値を活用するのがおすすめです。
7-3. 条件削除では削除対象リストを先に作る
条件に一致する要素を削除する場合は、削除対象のキーを先にリスト化します。
C#var keysToRemove = users
.Where(x => x.Value.StartsWith("A"))
.Select(x => x.Key)
.ToList();
foreach (var key in keysToRemove)
{
users.Remove(key);
}
このように、削除対象リストを作ってからRemoveすることで、foreach中にDictionaryを変更する問題を避けられます。
条件削除では、次の流れを意識すると安全です。
C#// 1. 条件に一致するキーを集める
// 2. 集めたキーをforeachで回す
// 3. Removeで削除する
7-4. 可読性を高めるメソッド化の例
削除処理が複数の場所に出てくる場合は、メソッド化すると読みやすくなります。
C#static bool RemoveUser(Dictionary<int, string> users, int userId)
{
return users.Remove(userId);
}
使う側は次のように書けます。
C#if (RemoveUser(users, userId))
{
Console.WriteLine("ユーザーを削除しました。");
}
else
{
Console.WriteLine("ユーザーが見つかりません。");
}
条件削除もメソッド化できます。
C#static void RemoveUsersStartingWith(
Dictionary<int, string> users,
string prefix)
{
var keysToRemove = users
.Where(x => x.Value.StartsWith(prefix))
.Select(x => x.Key)
.ToList();
foreach (var key in keysToRemove)
{
users.Remove(key);
}
}
呼び出し側は次のようになります。
C#RemoveUsersStartingWith(users, "A");
処理の意図がメソッド名に表れるため、コード全体の可読性が高くなります。
8. DictionaryのRemoveに関するよくある質問
8-1. Dictionaryから値を指定して削除できる?
DictionaryのRemoveはキーを指定して削除するメソッドです。そのため、値だけを指定して直接削除することはできません。
値を条件にして削除したい場合は、値に一致する要素のキーを探してから、そのキーを使って削除します。
C#Dictionary<string, int> prices = new Dictionary<string, int>
{
{ "apple", 120 },
{ "banana", 80 },
{ "orange", 100 }
};
var keysToRemove = prices
.Where(x => x.Value == 80)
.Select(x => x.Key)
.ToList();
foreach (var key in keysToRemove)
{
prices.Remove(key);
}
このコードでは、値が80の要素を削除しています。
値は重複する可能性がありますが、キーは重複しません。そのため、値を条件にする場合でも、最終的にはキーを使って削除します。
8-2. Removeで削除した要素は復元できる?
Removeで削除した要素は、Dictionaryから取り除かれます。Dictionary自体には、削除した要素を自動的に復元する機能はありません。
復元したい可能性がある場合は、削除前に値を別の変数に退避しておきます。
C#if (users.TryGetValue(userId, out string? userName))
{
users.Remove(userId);
// 必要であれば後で戻せる
users.Add(userId, userName);
}
または、削除前に別のDictionaryへバックアップする方法もあります。
C#Dictionary<int, string> removedUsers = new Dictionary<int, string>();
if (users.TryGetValue(userId, out string? userName))
{
removedUsers[userId] = userName;
users.Remove(userId);
}
削除後に復元する可能性がある処理では、削除前にデータを保存しておくことが重要です。
8-3. RemoveとClearはどちらを使うべき?
特定のキーだけ削除したい場合はRemoveを使います。
C#users.Remove(userId);
Dictionary内のすべての要素を削除したい場合はClearを使います。
C#users.Clear();
1件または一部の要素を削除するならRemove、すべて削除するならClearと考えるとわかりやすいです。
条件に一致する複数の要素を削除したい場合は、削除対象のキーをリスト化してからRemoveを繰り返します。
C#var keysToRemove = users
.Where(x => x.Value.Contains("test"))
.Select(x => x.Key)
.ToList();
foreach (var key in keysToRemove)
{
users.Remove(key);
}
8-4. Dictionaryの削除処理はパフォーマンスに影響する?
Dictionaryはキーを使った検索や削除が高速なコレクションです。通常の用途で、キーを指定してRemoveする処理が大きな問題になることは多くありません。
ただし、大量のデータに対して何度も条件削除を行う場合は、処理の書き方に注意が必要です。
たとえば、条件削除では次のように削除対象のキーを一度リスト化します。
C#var keysToRemove = dictionary
.Where(x => ShouldRemove(x))
.Select(x => x.Key)
.ToList();
foreach (var key in keysToRemove)
{
dictionary.Remove(key);
}
この方法は安全ですが、削除対象のキーリストを作るため、その分のメモリを使います。
多くのケースでは問題ありませんが、非常に大きなDictionaryを扱う場合は、データ構造や削除タイミングを見直すことも検討しましょう。
また、すべての要素を削除する場合は、Removeを繰り返すよりClearを使うほうが簡潔です。
C#dictionary.Clear();
目的に合わせてRemoveとClearを使い分けることで、読みやすく効率的なコードになります。
まとめ
C#のDictionaryで要素を削除する場合、基本的にはRemoveメソッドを使います。
Removeはキーを指定して1件の要素を削除するメソッドです。
C#dictionary.Remove(key);
削除できたかどうかを判定したい場合は、戻り値を使います。
C#if (dictionary.Remove(key))
{
Console.WriteLine("削除しました。");
}
else
{
Console.WriteLine("キーが存在しません。");
}
Dictionary内の要素をすべて削除したい場合は、RemoveではなくClearを使います。
C#dictionary.Clear();
値や条件に一致する要素を削除したい場合は、削除対象のキーを先に取得してからRemoveします。
C#var keysToRemove = dictionary
.Where(x => x.Value == targetValue)
.Select(x => x.Key)
.ToList();
foreach (var key in keysToRemove)
{
dictionary.Remove(key);
}
foreachでDictionaryを列挙している途中に直接Removeすると、InvalidOperationExceptionの原因になることがあります。条件削除では、削除対象のキーを先にリスト化するのが安全です。
C#のDictionary削除処理では、次の使い分けを覚えておきましょう。
C#// キーを指定して1件削除
dictionary.Remove(key);
// すべて削除
dictionary.Clear();
// 削除後の件数を確認
dictionary.Count;
Removeの戻り値やCountを活用すると、削除できたかどうかをわかりやすく判定できます。Dictionaryの削除処理を正しく使い分けて、読みやすく安全なC#コードを書きましょう。

