58

How can I change the value of a number of keys in a dictionary.

I have the following dictionary :

SortedDictionary<int,SortedDictionary<string,List<string>>>

I want to loop through this sorted dictionary and change the key to key+1 if the key value is greater than a certain amount.

Sam
  • 7,252
  • 16
  • 46
  • 65
Bernard Larouche
  • 1,211
  • 2
  • 13
  • 22
  • 10
    Why was this voted down? – keyboardP Dec 21 '09 at 02:23
  • 1
    This question sounds like you are trying to manually insert an item and keep it sorted (specifically, making room for one). Note the SortedDictionary does this for you already. – Russell Dec 21 '09 at 02:30

4 Answers4

50

As Jason said, you can't change the key of an existing dictionary entry. You'll have to remove/add using a new key like so:

// we need to cache the keys to update since we can't
// modify the collection during enumeration
var keysToUpdate = new List<int>();

foreach (var entry in dict)
{
    if (entry.Key < MinKeyValue)
    {
        keysToUpdate.Add(entry.Key);
    }
}

foreach (int keyToUpdate in keysToUpdate)
{
    SortedDictionary<string, List<string>> value = dict[keyToUpdate];

    int newKey = keyToUpdate + 1;

    // increment the key until arriving at one that doesn't already exist
    while (dict.ContainsKey(newKey))
    {
        newKey++;
    }

    dict.Remove(keyToUpdate);
    dict.Add(newKey, value);
}
Dan Tao
  • 125,917
  • 54
  • 300
  • 447
  • I think you might encounter an OutOfBoundsException with keyToUpdate +1 –  Dec 21 '09 at 02:39
  • @Roboto: You might get an `OverflowException` if `keyToUpdate == int.MaxValue`; other than that, though, I don't see how adding two integers is going to give an `OutOfBoundsException`... – Dan Tao Dec 21 '09 at 03:41
  • @Roboto: Maybe you meant on adding the new key to the dictionary? In that case, no, the `SortedDictionary.Add` method doesn't throw an `OutOfBoundsException`, only `ArgumentNullException` and `ArgumentException`; see http://msdn.microsoft.com/en-us/library/7620520y.aspx. – Dan Tao Dec 21 '09 at 03:44
26

You need to remove the items and re-add them with their new key. Per MSDN:

Keys must be immutable as long as they are used as keys in the SortedDictionary(TKey, TValue).

Matt Davis
  • 45,297
  • 16
  • 93
  • 124
jason
  • 236,483
  • 35
  • 423
  • 525
5

You can use LINQ statment for it

var maxValue = 10
sd= sd.ToDictionary(d => d.key > maxValue ? d.key : d.Key +1, d=> d.Value);
marcel
  • 313
  • 4
  • 10
2

If you don't mind recreating the dictionary, you could use a LINQ statment.

var dictionary = new SortedDictionary<int, SortedDictionary<string, List<string>>>();
var insertAt = 10;
var newValues = dictionary.ToDictionary(
    x => x.Key < insertAt ? x.Key : x.Key + 1,
    x => x.Value);
return new SortedDictionary<int, SortedDictionary<string, List<string>>>(newValues); 

or

var dictionary = new SortedDictionary<int, SortedDictionary<string, List<string>>>();
var insertAt = 10;
var newValues = dictionary.ToDictionary(
    x => x.Key < insertAt ? x.Key : x.Key + 1,
    x => x.Value);
dictionary.Clear();
foreach(var item in newValues) dictionary.Add(item.Key, item.Value);
goofballLogic
  • 37,883
  • 8
  • 44
  • 62