5

I have a dictionary with a Person and a Count value:

Dictionary<string, int> PersonDictionary = new Dictionary<string, int>();

It has the following values:

Sally, 6
Beth, 5
Mary, 5

I want to alternate each person and decrement the value by 1 each time it goes through the loop. I'm running into a real mind block on this one

What is the best way to get Sally and decrement by 1 and then go to Beth and decrement by 1 and then go to Mary and decrement by 1 and then go back to Sally... So on and so forth.

Just add further clarification I want to loop through this and use the owner.Key value and pass that to another method. So I need to be able to loop through this dictionary 1 at a time.

Update:

There are a few issues with my question. One issue was the decrementing the dictionary while in a loop. But my main question was how to iterate through each item [Sally -> Beth -> Mary -> Sally) until each persons value goes to 0 - That part is still the question at large.

webdad3
  • 8,893
  • 30
  • 121
  • 223
  • I'm missing something here. Why do you have an if and else? Dictionaries have unique keys so there is no reason to check for dupes. Just `PersonDictionary[owner.Key] = owner.Value - 1;` should work fine. – aquinas Jun 03 '18 at 16:58
  • Maybe you can clarify this: "Because it does it in order." What is the first "it" and the second "it" and what order are you referring to? – aquinas Jun 03 '18 at 17:03
  • @aquinas performing `foreach (var owner in personDictionary) personDictionary[owner.Key] = owner.Value - 1; ` will yield an `InvalidOperationException`, as setting a value in a dictionary updates its internal version number hence invalidates the iterator. – Ousmane D. Jun 03 '18 at 17:24
  • @Aominè, fair point, but just adding `ToList` fixes that. It *seemed* like maybe there was something else going on, but maybe not. OP seems to have vanished so we may never know :) – aquinas Jun 03 '18 at 19:46
  • Define: doesn't work. – Patrick Hofman Jun 03 '18 at 21:28
  • @PatrickHofman - I really want to know how to iterate through each person in this dictionary and decrementing by 1 each time. First Sally, then Beth, then Mary, then back to Sally. My code snipped doesn't work because I'm missing how to go through each item by name until there are no more values left. – webdad3 Jun 03 '18 at 21:30
  • A while loop..? – Patrick Hofman Jun 03 '18 at 21:33
  • @PatrickHofman - thanks that should work. – webdad3 Jun 03 '18 at 21:45

2 Answers2

6

Using Linq it would be as follows:

personDictionary = personDictionary.ToDictionary(e => e.Key, e => e.Value-1);
Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
  • 2
    Worth mentioning that this will create a *copy* of the `Dictionary` which may or may not be an unwanted effect – Fabjan Jun 03 '18 at 17:13
5

The above DOESN'T work.

It doesn't work because it's not possible to modify the collection inside of foreach loop and iterate through it at the same time.

That's why when we loop through the dictionary and try to modify it - an exception is thrown.

In order to change the same values without creating a copy of them we could iterate through a copy of Keys collection and use indexer:

foreach (var ownerKey in PersonDictionary.Keys.ToList())
{
    PersonDictionary[ownerKey]--;
}

This will copy the Keys but the Dictionary object itself and Values collection will remain the same. Or you could use Aominès solution if making a copy of the entire dictionary is not an issue.

Fabjan
  • 13,506
  • 4
  • 25
  • 52