Start learning free

LESSON 136 OF 674 · DICTIONARIES - CHALLENGES

Count a Vote in C#: Dictionary Counting with GetValueOrDefault

Practice Read the full explanation

You get votes, a Dictionary from names to how many votes each person has. You also get the name on a new vote.

Count the new vote and return votes.

The person called name gets one more vote. A name with no votes yet isn't in votes. It starts from 0, so after this vote it has 1. The order of the entries doesn't matter.

 

Example 1:

Input: votes = {"Ana": 3, "Ben": 5}, name = "Ana"
Output: {"Ana": 4, "Ben": 5}
Explanation: Ana had 3 votes. Now she has 3 + 1 = 4.

Example 2:

Input: votes = {"Ana": 3, "Ben": 5}, name = "Cara"
Output: {"Ana": 3, "Ben": 5, "Cara": 1}
Explanation: Cara had no votes yet. She starts from 0 and now has 1.

Example 3:

Input: votes = {}, name = "Max"
Output: {"Max": 1}
Explanation: This is the very first vote. Max now has 1.

 

Constraints:

  • votes can be empty.
  • Every count in votes is at least 1.
  • Names are single words made of English letters.
STEP 1 OF 3
    Ctrl + Enter to check

    C# · DICTIONARIES - CHALLENGES

    Count A Vote in C#, explained

    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

    1. Read the current count. votes.GetValueOrDefault(name, 0), stored in an int named count.
    2. 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.
    3. Return votes. Only the entry of name changed.

    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:

    • GetValueOrDefault lives in System.Collections.Generic and 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. Dictionary is 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] + 1 on a new name throws a KeyNotFoundException. On the second example the program would crash at Cara.
    • Forgetting to store. Computing count + 1 and not assigning it leaves votes unchanged.
    • Storing the old count. votes[name] = count never counts the new vote, and a new name would get 0.
    • Checking only for new names. An if that 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.
    Keep going with C#500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free