Problem overview
The method countVote gets votes, a scala.collection.mutable.Map[String, Int] from names to how many votes each person has, and the name on a new vote. It counts the vote and returns the map. The person called name gets one more vote. A name with no votes yet isn't in the map, and it starts from 0, so after its first vote it has 1. The order of the entries doesn't matter.
For {"Ana": 3, "Ben": 5} and "Ana", Ana goes from 3 to 4. For the same map and "Cara", a new key "Cara" appears with 1. For an empty map and "Max", the result is {"Max": 1}.
Approach
Both cases, an existing name and a new one, follow the same rule: read the current count, using 0 when the name is missing, add 1, and store the result under the same key. getOrElse(name, 0) does the first part without throwing. Assigning to the key does the last part: it adds the key when it is new and replaces the count when it exists. No if is needed.
Step by step
- Read the count so far into a
valnamedcount, withvotes.getOrElse(name, 0). A name with no votes isn't a key, andgetOrElsegives 0 for it. - Store one more:
votes(name) = count + 1. - Return
votes. Only the entry ofnamechanged.
The solution in Scala
class Solution {
def countVote(votes: scala.collection.mutable.Map[String, Int], name: String): scala.collection.mutable.Map[String, Int] = {
val count = votes.getOrElse(name, 0)
votes(name) = count + 1
return votes
}
}
Details on the Scala:
- The reading and the writing are two separate steps.
getOrElseonly reads; the key is added by the assignment on the next line. - Using
votes(name)to read would throwjava.util.NoSuchElementException: key not found: Maxthe first time a name is counted.getOrElseis what avoids that. votes(name) = count + 1works for both new and existing keys on a mutable map.
Another way
The two lines can be joined: votes(name) = votes.getOrElse(name, 0) + 1. With {"Ana": 3}, counting "Ana" and then "Cara" gives Ana: 4, Cara: 1. The lesson's version keeps the old count in its own val so you can see the read and the write as separate steps.
Why 0 is the right default
A person with no votes has zero votes, so counting from 0 is not a trick, it is the true starting point. The map just doesn't list people who have none. The default lets one rule cover every case: new count = old count + 1, where the old count is 0 for someone not listed. The same shape works for any tally, such as words in a sentence or visits to a page.
Running it
Results for the three examples, as key: value lines sorted by key, the way the lesson's tests print them:
Ana: 4
Ben: 5
Ana: 3
Ben: 5
Cara: 1
Max: 1
Edge cases and common mistakes
- Reading with parentheses.
votes(name) = votes(name) + 1works for a name that is already counted and throws for a new one. - Writing 1 for everyone. Setting
votes(name) = 1would reset a name that already has votes. - An empty map. The default 0 makes this case work with no special code.
- Counting the wrong key. The other entries must stay as they were. Only the key
nameis written.
