How to iterate over a dictionary and change values?

Dictionary<string,double> myDict = new Dictionary(); //... foreach (KeyValuePair<string,double> kvp in myDict) { kvp.Value = Math.Round(kvp.Value, 3); } 

I get an error: "Property or indexer" System.Collections.Generic.KeyValuePair.Value 'cannot be assigned - it is read-only ".
How can I iterate through myDict and change the values?

+61
dictionary
Feb 14 '10 at 7:39
source share
8 answers

According to MSDN :

The foreach statement is a wrapper around the counter, which allows only reading from the collection and not writing to it.

Use this:

 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); } 
+94
Feb 14 '10 at 7:50
source share

For lazy programmers:

 Dictionary<string, double> dictionary = new Dictionary<string, double>(); foreach (var key in dictionary.Keys.ToList()) { dictionary[key] = Math.Round(dictionary[key], 3); } 
+29
May 24 '12 at 16:57
source share

You should not change the dictionary during iteration, otherwise you will get an exception.

So, first copy the key-value pairs to the topic list, then go to this topic list and then change the dictionary:

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

(on my car):

a = 2.2
b = 77777,333
c = 2,346

Note : in terms of performance, this solution is slightly better than the currently hosted solutions, since the value is already assigned by the key and there is no need to retrieve it again from the dictionary object.

+8
Feb 14 2018-10-14T00
source share

One solution would be to put the keys in a list (or another collection) in advance and iterate over them when changing the dictionary:

 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); } 
+1
Oct 06 2018-11-11T00:
source share

I noticed that the fastest way (at the moment) is to repeat using the dictionary with the modification:

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

The first takes about 2.2 seconds, and the second takes 4.5 s (the dictionary size is 1000 and repeated 10k times, changing the dictionary size to 10 did not change the coefficients). There was also no big deal with getting a list of keys, the value of the [key] get dictionary is just a slow VS built on iteration. In addition, if you want an even higher speed to use the hard coded type for the silent ("Test") class, with this I got it about 1.85 s (from hardcoded to "object").

EDIT:

Anna has sent the same solution before: https://stackoverflow.com/a/316618/

+1
Aug 17 '13 at 12:18
source share

some time has passed, but maybe someone is interested in this:

 yourDict = yourDict.ToDictionary(kv => kv.Key, kv => Math.Round(kv.Value, 3)) 
+1
Jan 05 '17 at 23:18
source share

Dictionary iteration is not directly possible, because you get an exception (as Ron already said), you don’t need to use a topic list to solve the problem.

Instead, use the foreach , but for to iterate through the dictionary and change the values ​​with indexed access:

 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); } 
0
Mar 17 2018-11-11T00:
source share

Scroll keys in the dictionary, not KeyValuePairs.

 Dictionary<string, double> myDict = new Dictionary<string, double>(); //... foreach (string key in myDict.Keys) { myDict[key] = Math.Round(myDict[key], 3); } 
-2
Feb 14 2018-10-14T00
source share



All Articles