Dictionary enumeration in C#

北慕城南 提交于 2019-12-30 01:40:09

问题


How do I enumerate a dictionary?

Suppose I use foreach() for dictionay enumeration. I can't update a key/value pair inside foreach(). So I want some other method.


回答1:


To enumerate a dictionary you either enumerate the values within it:

Dictionary<int, string> dic;

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

or the KeyValuePairs

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

or the keys

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

If you wish to update the items within the dictionary you need to do so slightly differently, because you can't update the instance while enumerating. What you'll need to do is enumerate a different collection that isn't being updated, like so:

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
}

To remove items, do so in a similar way, enumerating the collection of items we want to remove rather than the dictionary itself.

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



回答2:


In answer to the problem "I can't update value/key inside foreach()", you cannot modify a collection while enumerating it. I would approach this by making a copy of the Keys collection:

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

//...fill the dictionary

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



回答3:


Foreach. There are three ways: You can enumerate over the Keys property, over the Values property or over the dictionary itself which is an enumerator of KeyValuePair<TKey, TValue>.




回答4:


I just answered the same (updated) question for lists, so here's the same thing for dictionaries.

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);
}

Note that we have to do the updates outside the loop, so we aren't modifying the dictionary as we enumerate it. Also this detects clashes caused by making two keys the same - it will throw (due to the use of Add).

Example - make all keys lowercase and trim all values, with a Dictionary<string, string>:

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

If the keys are not unique when made lowercase, this will throw.



来源:https://stackoverflow.com/questions/676880/dictionary-enumeration-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!