Problem overview
The method CountVote receives votes, a Dictionary<string, int> from names to how many votes each person has, and the name on a new vote. It counts the vote and returns votes. The person called name gets one more vote. A name with no votes yet is not in votes at all: it starts from 0 and ends with 1. The order of the entries does not matter.
With Ana at 3 and Ben at 5, a vote for Ana makes it 4. A vote for Cara, who has no entry, adds her with 1. In an empty dictionary, the very first vote for Max gives him 1.
Approach
There are two cases: the name is already a key, or it is not. Both have the same answer if you treat a missing name as having 0 votes: the new count is the old count plus 1. So the only job is to read the old count safely.
Reading votes[name] directly throws a KeyNotFoundException for a new name. GetValueOrDefault(name, 0) returns the stored count when the key exists and 0 when it does not, and it does not add the key. Then a plain assignment, votes[name] = count + 1, either adds the new key or replaces the old count. No if is needed.
Step by step
- Read the current count.
votes.GetValueOrDefault(name, 0), stored in anintnamedcount. - Store the new count.
votes[name] = count + 1. For a new name this adds the key with 1 vote. For a name with votes it replaces the old number. - Return
votes. Only the entry ofnamechanged.
The solution in C#
class Solution {
public Dictionary<string, int> CountVote(Dictionary<string, int> votes, string name) {
int count = votes.GetValueOrDefault(name, 0);
votes[name] = count + 1;
return votes;
}
}
On the three examples it returns these dictionaries, printed as key: value lines sorted by key, the form the lesson's tests use:
Ana: 4
Ben: 5
Ana: 3
Ben: 5
Cara: 1
Max: 1
The C# details worth knowing:
GetValueOrDefaultlives inSystem.Collections.Genericand works on dictionaries. It never throws for a missing key.- The index setter adds or replaces. Assigning to a key that is not there creates it. Assigning to one that is there overwrites it. Reading, on the other hand, throws for a missing key, which is why the read and the write are done differently.
- The dictionary is changed in place.
Dictionaryis a reference type, so the caller's dictionary is the one that changes. The method returns the same object. - The shorter form
votes[name] = votes.GetValueOrDefault(name, 0) + 1;does the same in one line. The lesson splits it so each step is visible.
Edge cases and common mistakes
- Reading with the index.
votes[name] + 1on a new name throws aKeyNotFoundException. On the second example the program would crash at Cara. - Forgetting to store. Computing
count + 1and not assigning it leavesvotesunchanged. - Storing the old count.
votes[name] = countnever counts the new vote, and a new name would get 0. - Checking only for new names. An
ifthat adds missing names with 1 but forgets to increase existing ones fails the first example. - Empty dictionary. It works as it is: the first read gives 0, and the first store gives 1.
Testing
{"Ana": 3, "Ben": 5},"Ana"gives{"Ana": 4, "Ben": 5}.{"Ana": 3, "Ben": 5},"Cara"gives{"Ana": 3, "Ben": 5, "Cara": 1}.{},"Max"gives{"Max": 1}.- A name voted for twice in a row ends with its count raised by 2.
