views:

626

answers:

3

How do I alter the contents of an IDictionary using C# 3.0 (Linq, Linq extensions) ?

var enumerable = new int [] { 1, 2};
var dictionary = enumerable.ToDictionary(a=>a,a=>0);
//some code
//now I want to change all values to 1 without recreating the dictionary
//how it is done?
+5  A: 

LINQ is a query dialect - it isn't directly a mutation language.

To change the values of an existing dictionary, foreach is probably your friend:

foreach(int key in dictionary.Keys) {
    dictionary[key] = 1;
}
Marc Gravell
Wouldn't it be nice if it was also a mutation language?
Jader Dias
It is what it is...
Marc Gravell
This gives a runtime error about the collection changing during the enumeration, and that the foreach loop cannot continue.
pauldoo
+2  A: 
foreach (var item in dictionary.Keys)
    dictionary[item] = 1;

I wonder why you might a need doing such a thing, though.

Mehrdad Afshari
It was an oversimplification.
Jader Dias
+2  A: 

This is not nearly as clear as other ways, but it should work fine:

dictionary.Keys.ToList().ForEach(i => dictionary[i] = 0);

My other alternative would have been to make a ForEach extension method similar to this:

public static class MyExtensions
{
    public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
    {
        foreach (var item in items)
        {
            action(item);
        }
    }
}

Then use it like this:

dictionary.ForEach(kvp => kvp.Value = 0);

This won't work in this case though, as Value cannot be assigned to.

Ryan Versaw
So basically, I would never use the first piece of code in reality. The extension method can be great, but as Value cannot be assigned to, dictionaries don't allow for much.
Ryan Versaw
Not as clear *and* less efficient (creates a cloned list of the keys, and does 2 iterations instead of 1)... a winner!
Marc Gravell