How to iterate through Dictionary and change values?

Viewed 82628
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 to -- it is read only."
How can I iterate through myDict and change values?

8 Answers

According to MSDN:

The foreach statement is a wrapper around the enumerator, which allows only reading from the collection, 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);
}

You shouldn't change the dictionary while iterating it, otherwise you get an exception.

So first copy the key-value pairs to a temp list and then iterate through this temp list and then change your 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();

output (on my machine):

a = 2.2
b = 77777.333
c = 2.346

Note: in terms of performance, this solution is a bit better than currently posted solutions, since the value is already assigned with the key, and there's no need to fetch it again from the dictionary object.

Loop through the keys in the dictionary, not the KeyValuePairs.

Dictionary<string, double> myDict = new Dictionary<string, double>();
//...
foreach (string key in myDict.Keys)
{
    myDict[key] = Math.Round(myDict[key], 3);
}
Related