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
- Create a variable named
count, declared withlet, and start it at 0. It will hold how many votes the name has so far. - Write an
ifthat checks whethernameis a key ofvoteswith theinoperator, and in its body setcounttovotes[name]. For a missing name,votes[name]would beundefined, not 0, which is why the check is there. - After the
if, storecount + 1under the keyname. For a new name this adds the key with 1 vote. For a name that has votes, it replaces the old count. - 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
NaNunless 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.
