如何遍历字典和更改值?
Dictionary<string,double> myDict = new Dictionary(); //... foreach (KeyValuePair<string,double> kvp in myDict) { kvp.Value = Math.Round(kvp.Value, 3); }
我收到一个错误:“属性或索引器”System.Collections.Generic.KeyValuePair.Value“不能被分配给 – 它是只读的。
我如何迭代myDict
并更改值?
根据MSDN :
foreach语句是枚举器的一个包装,它只允许从集合中读取,而不是写入。
用这个:
var dictionary = new Dictionary<string, double>(); // TODO Populate your dictionary here var keys = new List<string>(dictionary.Keys); foreach (string key in keys) { dictionary[key] = Math.Round(dictionary[key], 3); }
对于懒惰的程序员:
Dictionary<string, double> dictionary = new Dictionary<string, double>(); foreach (var key in dictionary.Keys.ToList()) { dictionary[key] = Math.Round(dictionary[key], 3); }
迭代时不应该更改字典,否则会得到exception。
因此,首先将键值对复制到一个临时列表,然后遍历这个临时列表,然后更改您的字典:
Dictionary<string, double> myDict = new Dictionary<string, double>(); // a few values to play with myDict["a"] = 2.200001; myDict["b"] = 77777.3333; myDict["c"] = 2.3459999999; // prepare the temp list List<KeyValuePair<string, double>> list = new List<KeyValuePair<string, double>>(myDict); // iterate through the list and then change the dictionary object foreach (KeyValuePair<string, double> kvp in list) { myDict[kvp.Key] = Math.Round(kvp.Value, 3); } // print the output foreach (var pair in myDict) { Console.WriteLine(pair.Key + " = " + pair.Value); } // uncomment if needed // Console.ReadLine();
输出(在我的机器上):
a = 2.2
b = 77777.333
c = 2.346
注意 :就性能而言,这个解决scheme比当前发布的解决scheme要好一些,因为这个值已经被赋值了,并且不需要再从字典对象中获取它。
我注意到,最快的方式(在这一刻)迭代字典与修改是:
//Just a dumb class class Test<T> { public T value; public Test() { } public Test(T v) { value = v; } } Dictionary<int, Test<object>> dic = new Dictionary<int, Test<object>>(); //Init dictionary foreach (KeyValuePair<int, Test> pair in dic) { pair.Value.value = TheObject;//Modify }
VS
List<int> keys = new List<int>(dic.Keys); //This is fast operation foreach (int key in keys) { dic[key] = TheObject; }
第一个约2.2s和第二个4.5s(testing字典大小1000和重复10k时间,改变字典大小为10没有改变比例)。 另外,获取密钥列表并没有什么大不了的,字典[键]值得到只是缓慢的VS内置迭代。 此外,如果你想更多的速度使用硬编码types愚蠢(“testing”)类,与我得到它约1.85s(硬编码为“对象”)。
编辑:
安娜在之前发布了相同的解决scheme: https : //stackoverflow.com/a/6515474/766304
一种解决scheme是将键放入列表(或另一个集合)中,并在更改字典时遍历它们:
Dictionary<string, double> dictionary = new Dictionary<string, double>(); // Populate it List<string> keys = new List<string>(dictionary.Keys); foreach (string key in keys) { dictionary[key] = Math.Round(dictionary[key], 3); }
虽然直接迭代字典是不可能的,因为你得到一个exception(像罗恩已经说过的),你不需要使用临时列表来解决问题。
而不是使用foreach
,而是使用for
循环遍历字典,并使用索引访问来更改值:
Dictionary<string, double> myDict = new Dictionary<string,double>(); //... for(int i = 0; i < myDict.Count; i++) { myDict[myDict.ElementAt(i).Key] = Math.Round(myDict.ElementAt(i).Value, 3); }
过了一段时间,但也许有人对此感兴趣:
yourDict = yourDict.ToDictionary(kv => k.Key, kv => Math.Round(kv.Value, 3))
通过字典中的键循环,而不是KeyValuePair。
Dictionary<string, double> myDict = new Dictionary<string, double>(); //... foreach (string key in myDict.Keys) { myDict[key] = Math.Round(myDict[key], 3); }