Start learning free

LESSON 137 OF 677 · DICTIONARIES - CHALLENGES

Count a Vote in Scala

Practice Read the full explanation

You get votes, a mutable.Map 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

    SCALA · DICTIONARIES - CHALLENGES

    Count A Vote in Scala, explained

    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

    1. Read the count so far into a val named count, with votes.getOrElse(name, 0). A name with no votes isn't a key, and getOrElse gives 0 for it.
    2. Store one more: votes(name) = count + 1.
    3. Return votes. Only the entry of name changed.

    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. getOrElse only reads; the key is added by the assignment on the next line.
    • Using votes(name) to read would throw java.util.NoSuchElementException: key not found: Max the first time a name is counted. getOrElse is what avoids that.
    • votes(name) = count + 1 works 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) + 1 works for a name that is already counted and throws for a new one.
    • Writing 1 for everyone. Setting votes(name) = 1 would 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 name is written.
    Keep going with Scala500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free