【发布时间】:2010-10-15 04:21:36
【问题描述】:
如何枚举字典?
假设我使用foreach() 进行字典枚举。我无法更新foreach() 中的键/值对。所以我想要一些其他的方法。
【问题讨论】:
标签: c# .net dictionary enumeration
如何枚举字典?
假设我使用foreach() 进行字典枚举。我无法更新foreach() 中的键/值对。所以我想要一些其他的方法。
【问题讨论】:
标签: c# .net dictionary enumeration
要枚举字典,您可以枚举其中的值:
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);
}
【讨论】:
在回答“我无法在 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);
}
【讨论】:
Foreach。有三种方法:您可以枚举Keys 属性、Values 属性或字典本身,它是KeyValuePair<TKey, TValue> 的枚举器。
【讨论】:
我刚刚回答了关于列表的相同(更新的)问题,所以对于字典也是如此。
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);
}
请注意,我们必须在循环之外进行更新,因此我们不会在枚举字典时对其进行修改。这也检测到由于使两个键相同而导致的冲突 - 它会抛出(由于使用Add)。
示例 - 使用 Dictionary<string, string> 将所有键设为小写并修剪所有值:
myDict.MutateEach(key => key.ToLower(), value => value.Trim());
如果键在小写时不是唯一的,则会抛出。
【讨论】: