web-dev-qa-db-ja.com

C#での辞書の列挙

辞書を列挙するにはどうすればよいですか?

辞書の列挙にforeach()を使用するとします。 foreach()内のキーと値のペアを更新できません。だから私はいくつかの他の方法が欲しい。

25
Ravi

辞書を列挙するには、その中の値を列挙します。

Dictionary<int, string> dic;

foreach(string s in dic.Values)
{
   Console.WriteLine(s);
}

またはKeyValuePairs

foreach(KeyValuePair<int, string> kvp in dic)
{
   Console.WriteLine("Key : " + kvp.Key.ToString() + ", Value : " + kvp.Value);
}

またはキー

foreach(int key in dic.Keys)
{
    Console.WriteLine(key.ToString());
}

ディクショナリ内のアイテムを更新する場合は、列挙中にインスタンスを更新できないため、少し異なる方法で更新する必要があります。次のように、更新されていない別のコレクションを列挙する必要があります。

Dictionary<int, string> newValues = new Dictionary<int, string>() { 1, "Test" };
foreach(KeyValuePair<int, string> kvp in newValues)
{
   dic[kvp.Key] = kvp.Value; // will automatically add the item if it's not there
}

アイテムを削除するには、同様の方法で削除します。ディクショナリ自体ではなく、削除するアイテムのコレクションを列挙します。

List<int> keys = new List<int>() { 1, 3 };
foreach(int key in keys)
{
   dic.Remove(key);
}
81
Ian

「foreach()内の値/キーを更新できない」という問題の解決策として、列挙中にコレクションを変更することはできません。 Keysコレクションのコピーを作成して、これに取り組みます。

Dictionary<int,int> dic=new Dictionary<int, int>();

//...fill the dictionary

int[] keys = dic.Keys.ToArray();
foreach (int i in keys)
{
    dic.Remove(i);
}
9
spender

Foreach。 3つの方法があります:Keysプロパティ、Valuesプロパティ、またはKeyValuePair<TKey, TValue>の列挙子であるディクショナリ自体を列挙できます。

8
Matthias Meid

リストに対する同じ(更新された)質問に答えただけなので、辞書についても同じです。

public static void MutateEach(this IDictionary<TKey, TValue> dict, Func<TKey, TValue, KeyValuePair<TKey, TValue>> mutator)
{
    var removals = new List<TKey>();
    var additions = new List<KeyValuePair<TKey, TValue>>();

    foreach (var pair in dict)
    {
        var newPair = mutator(pair.Key, pair.Value);
        if ((newPair.Key != pair.Key) || (newPair.Value != pair.Value))
        {
            removals.Add(pair.Key);
            additions.Add(newPair);
        }
    }

    foreach (var removal in removals)
        dict.Remove(removal);

    foreach (var addition in additions)
        dict.Add(addition.Key, addition.Value);
}

ループの外で更新を行う必要があるので、列挙するときに辞書を変更しないことに注意してください。また、これは2つのキーを同じにすることによって引き起こされるクラッシュを検出します-(Addの使用により)スローされます。

例-Dictionary<string, string>を使用して、すべてのキーを小文字にし、すべての値をトリムします。

myDict.MutateEach(key => key.ToLower(), value => value.Trim());

小文字にしたときにキーが一意でない場合は、スローされます。

2