Start learning free

LESSON 223 OF 671 · LOOPS WITH STRINGS, ARRAYS & DICTIONARIES

Top Scorer in JavaScript: Best Key in an Object

Practice Read the full explanation

You get scores, a dictionary from players' names to their scores. Return the name of the player with the highest score.

Several players may share the highest score. Then return the name that comes first in alphabetical order.

 

Example 1:

Input: scores = {"Ana": 90, "Ben": 75, "Cara": 88}
Output: "Ana"
Explanation: 90 is the highest score, and it is Ana's.

Example 2:

Input: scores = {"Zoe": 82, "Ana": 82}
Output: "Ana"
Explanation: Both have 82. "Ana" comes before "Zoe" in alphabetical order.

Example 3:

Input: scores = {"Max": 0}
Output: "Max"
Explanation: Max is the only player, so his score is the highest.

 

Constraints:

  • scores has at least one name.
  • Every score is a whole number from 0 to 100.
  • Each name is a capital letter followed by lowercase letters, like "Ana".
STEP 1 OF 6
    Ctrl + Enter to check

    JAVASCRIPT · LOOPS WITH STRINGS, ARRAYS & DICTIONARIES

    Top Scorer in JavaScript, explained

    Problem overview

    The method topScorer gets scores, an object that maps each player's name to a score, and returns the name of the player with the highest score. If several players share the highest score, it returns the name that comes first alphabetically. Scores are whole numbers from 0 to 100, and there is at least one player.

    For {"Ana": 90, "Ben": 75, "Cara": 88} the answer is "Ana". For {"Zoe": 82, "Ana": 82} both have 82, so the answer is "Ana", which comes before "Zoe". For {"Max": 0} the only player wins, even with a score of 0.

    Approach

    Keep the best player seen so far, and look at every player once. Each player either beats the current best or doesn't. A player beats it when the score is higher, or when the score is equal and the name comes earlier alphabetically.

    The tie rule matters because the order in which a loop visits an object is not something to rely on. If the code only checked "higher score", a tie would be won by whoever the loop visits first, and the result would depend on how the object was written. Comparing names on a tie makes the answer the same for any order.

    Step by step

    1. Set up the best so far: bestName is an empty string and bestScore is -1, both with let because they change. Every real score is at least 0, so the first player always beats -1.
    2. Loop over the keys with for (const name in scores). for...in gives the keys of an object, one at a time.
    3. Read the score of the current key into a constant: scores[name].
    4. Check whether this player wins: a higher score, or an equal score and a name that comes first. The tie check pairs "equal score" with "earlier name", so a lower score never wins on its name alone. Parentheses make that grouping easy to read.
    5. Update the best name and score inside the if.
    6. Return bestName after the loop, once everyone has been compared.

    The solution in JavaScript

    class Solution {
        topScorer(scores) {
            let bestName = "";
            let bestScore = -1;
            for (const name in scores) {
                const score = scores[name];
                if (score > bestScore || (score == bestScore && name < bestName)) {
                    bestName = name;
                    bestScore = score;
                }
            }
            return bestName;
        }
    }
    

    Two details are worth knowing:

    • Comparing strings with <. On two strings, < compares them character by character in dictionary order, as long as the case matches. "Ana" < "Zoe" is true and "Zoe" < "Ana" is false. All names here are a capital letter followed by lowercase letters, so the comparison behaves the way you expect. A lowercase "ana" would sort after "Zoe", because every capital letter comes before every lowercase letter.
    • == on numbers. Both sides are numbers, so == works. Many people write === out of habit, which gives the same result here.

    Testing

    Running the method on the statement's examples gives:

    Ana
    Ana
    Max
    

    The tie case gives Ana whichever way the object is written: {"Zoe": 82, "Ana": 82} and {"Ana": 82, "Zoe": 82} both return Ana.

    Common mistakes

    • Skipping the tie rule. With only score > bestScore, the first player visited keeps a tie. The same code returns Zoe for {"Zoe": 82, "Ana": 82} and Ana for {"Ana": 82, "Zoe": 82}.
    • Starting bestScore at 0. Then a lone player with a score of 0, like Max, never beats it, and the function returns an empty string. Starting at -1 avoids that.
    • Returning the score instead of the name. The loop tracks both; the function returns bestName.
    Keep going with JavaScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free