Splitting all dictionary values ​​by value

I have the following code in C # where vector is the [string, double] dictionary type. I want to split all the values ​​in this dictionary by the value "magnitude". Now my naive first code was as follows:

foreach (var key in vector.Keys)
{
    vector[key] = vector[key] / magnitude;
}

      

Which throws an exception saying the collection has been modified in foreach. I can create a second dictionary to record the resulting values, but I don't want that.

Is there an easier way to do this, for example using methods that work with all values ​​of the dictionary, such as the following:

vector.Values().Aggreagate(), vector.Values().Average() 

      

+3


source to share


6 answers


The easiest way to do this is to just copy the list of keys before iterating:

foreach (var key in vector.Keys.ToList())
{
    vector[key] = vector[key] / magnitude;
}

      

Or:

foreach (var entry in vector.ToList())
{
    vector[entry.Key] = entry.Value / magnitude;
}

      

(This avoids double searches, but will of course copy more data.)



It's a bit of a shame that changing the value of an existing entry is treated as a change, which is admittedly preventing you from continuing to iterate over the keys.

An alternative would be to have a mutable wrapper type as value, then you could use:

foreach (var wrapper in vector.Values)
{        
    wrapper.Value = wrapper.Value / 10;
}

      

This will not modify the dictionary at all - just the objects that the dictionary refers to. I personally haven't done this most of the time, but it might be fine for you.

+8


source


This is, of course, because you are modifying the dictionary during iteration. You can try repeating a copy Keys

instead of the actual collection



foreach (var key in vector.Keys.ToList())
{
    vector[key] = vector[key] / magnitude;
}

      

+4


source


You can avoid changing the collection by copying it like this.

var CopiedKeys = vector.Keys.ToList();
foreach (var key in CopiedKeys)
{
    vector[key] = vector[key] / magnitude;
}

      

+3


source


        dictionary = dictionary.ToDictionary(x => x.Key, x => x.Value / magnitude);

      

+2


source


An alternative could be to use an incremental iterator

int magnitude = 2;
for (int index = 0; index < vector.Count; index++)
{
     String key = vector.ElementAt(index).Key;
     vector[key] = vector[key] / magnitude;
}

      

+1


source


One of the simplest ways is to use a regular one for iteration, like this sample:

        for (int i = 0; i < vector.Keys.Count; i++)
        {
            string key = vector.Keys.ElementAt(i);
            vector[key] /= magnitude;
        }

      

if you want to use Linq methods you can use this code:

vector=vector
            .Select(x=> new KeyValuePair<string,double>(x.Key,x.Value/magnitude))
            .ToDictionary( x=>x.Key,x=>x.Value);

      

0


source







All Articles