Start learning free

LESSON 134 OF 671 · DICTIONARIES - CHALLENGES

Count a Vote in JavaScript: Adding to a Count That May Not Exist

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 4
    Ctrl + Enter to check

    JAVASCRIPT · DICTIONARIES - CHALLENGES

    Count A Vote in JavaScript, explained

    Problem overview

    The method countVote receives votes, an object that maps names to how many votes each person has, and the name on a new vote. It counts the new vote and returns votes. The person called name gets one more vote. A name with no votes yet is not a key of votes: it starts from 0, so after this vote it has 1. The order of the entries does not matter.

    The constraints say votes can be empty, every count in it is at least 1, and names are single words made of English letters.

    The examples:

    • A vote for "Ana" in {"Ana": 3, "Ben": 5} gives {"Ana": 4, "Ben": 5}.
    • A vote for "Cara" in the same book gives {"Ana": 3, "Ben": 5, "Cara": 1}. Cara is new and starts from 0.
    • A vote for "Max" in {} gives {"Max": 1}.

    Approach

    There are two cases, but the final step is the same in both: store the current count plus 1 under the name. What differs is the current count. For a known name it is the stored number, and for a new name it is 0.

    So we do not need two branches that each write to the object. We use the pattern of starting with the default and letting an if replace it: a variable count starts at 0, and when the name is a key, it is replaced by the stored value. After that, a single assignment handles everyone.

    Step by step

    1. Create a variable named count, declared with let, and start it at 0. It will hold how many votes the name has so far.
    2. Write an if that checks whether name is a key of votes with the in operator, and in its body set count to votes[name]. For a missing name, votes[name] would be undefined, not 0, which is why the check is there.
    3. After the if, store count + 1 under the key name. For a new name this adds the key with 1 vote. For a name that has votes, it replaces the old count.
    4. Return votes.

    The solution in JavaScript

    class Solution {
        countVote(votes, name) {
            let count = 0;
            if (name in votes) {
                count = votes[name];
            }
            votes[name] = count + 1;
            return votes;
        }
    }
    

    Details worth knowing

    If you skip the check and write votes[name] + 1 for a new name, the sum is undefined + 1, which is NaN. Printing the book then shows null in JSON, and the number is lost. For a name that is not there yet, a bare votes["Max"] += 1 on an empty object leaves {"Max":null} when printed with JSON.stringify, and reading it back gives NaN.

    A shorter version of the same logic is votes[name] = (votes[name] ?? 0) + 1, where ?? supplies 0 when the left side is undefined. The lesson's version spells the steps out with in.

    The method changes the object it was given and returns that same object.

    Testing

    Running the method on the three examples and printing each result with JSON.stringify gives:

    {"Ana":4,"Ben":5}
    {"Ana":3,"Ben":5,"Cara":1}
    {"Max":1}
    

    Edge cases and common mistakes

    • Doing the arithmetic on a missing key. A new name gives NaN unless the default is applied first.
    • Starting the count at 1 for everyone. The default is 0 because the new vote is added afterwards. Starting at 1 would give a new name 2 votes.
    • Assigning only inside the if. If the store sits inside the braces, a new name is never added. The assignment belongs after the block.
    • Forgetting the return. The tests look at the returned object.
    Keep going with JavaScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free