Start learning free

LESSON 269 OF 675 · TUPLES, SORTING & BUILT-INS

Leaderboard in TypeScript: Sorting Tuples by Score and Name

Practice Read the full explanation

You get an array of players, players. Each player is a pair: a name and a score, like ("Ava", 30).

Return the names, from the highest score to the lowest.

Players with the same score go in alphabetical order of their names.

The starter code shows how your language holds a pair.

 

Example 1:

Input: players = [("Ava", 30), ("Ben", 25), ("Cy", 40)]
Output: ["Cy", "Ava", "Ben"]
Explanation: Cy has the most points, 40.
Then come Ava with 30 and Ben with 25.

Example 2:

Input: players = [("Mia", 50), ("Leo", 70), ("Ava", 50)]
Output: ["Leo", "Ava", "Mia"]
Explanation: Leo leads with 70.
Ava and Mia both have 50.
Ava comes first from A to Z.

Example 3:

Input: players = [("Zoe", 0)]
Output: ["Zoe"]
Explanation: Zoe is the only player.

 

Constraints:

  • players has 1 to 100 players.
  • Every score is a whole number from 0 to 1000.
  • Each name is a capital letter followed by lowercase letters, like "Ava".
  • No two players have the same name.
STEP 1 OF 6
    Ctrl + Enter to check

    TYPESCRIPT · TUPLES, SORTING & BUILT-INS

    Leaderboard in TypeScript, explained

    Problem overview

    The method leaderboard gets an array players. Each player is a tuple [string, number]: a name and a score. It returns the names only, from the highest score to the lowest. Players with the same score go in alphabetical order of their names. There are 1 to 100 players, scores run from 0 to 1000, and no two players share a name.

    For [["Ava", 30], ["Ben", 25], ["Cy", 40]] the result is ["Cy", "Ava", "Ben"]. For [["Mia", 50], ["Leo", 70], ["Ava", 50]] it is ["Leo", "Ava", "Mia"]: Leo leads with 70, and Ava comes before Mia among the two 50s. For [["Zoe", 0]] it is ["Zoe"].

    Approach

    Two steps: sort the pairs, then collect the names.

    The sort uses a compare function with two rules. In a pair, index 0 is the name and index 1 is the score. If the scores differ, the higher score goes first, so return b[1] - a[1]. This is negative when a has more points, which puts a first. If the scores are equal, return a[0].localeCompare(b[0]), which orders the names from A to Z.

    After the sort the pairs are in the right order, so a loop that pushes each name into a new array produces the answer.

    Step by step

    1. Call players.sort with a function of a and b whose first rule returns b[1] - a[1] when the scores differ.
    2. Add the second rule for equal scores: a[0].localeCompare(b[0]).
    3. Start an empty string[] called names.
    4. Loop over players with for (const [name, score] of players), which unpacks each pair into two constants.
    5. Push name onto names inside the loop.
    6. Return names after the loop.

    The solution in TypeScript

    class Solution {
        leaderboard(players: [string, number][]): string[] {
            players.sort((a, b) => {
                if (a[1] !== b[1]) {
                    return b[1] - a[1];
                }
                return a[0].localeCompare(b[0]);
            });
            let names: string[] = [];
            for (const [name, score] of players) {
                names.push(name);
            }
            return names;
        }
    }
    

    The type [string, number][] is an array of tuples. The destructuring in the loop, const [name, score], names the two parts of the pair. The loop never uses score, and that is fine: TypeScript does not flag unused variables here.

    Notice the direction of each subtraction. For ascending order you write a - b; for descending order, b - a. The name rule is ascending, so it keeps a on the left.

    A compare function that returns b[1] - a[1] for the score and a text comparison for the name is the usual way to sort by a main key with a tie-break. Sorting changes the players array in place; the method returns a new array of names.

    Tracing the second example

    With [["Mia", 50], ["Leo", 70], ["Ava", 50]], comparing Leo with Mia: the scores differ, so b[1] - a[1] decides, and Leo's 70 puts him first. Comparing Ava with Mia: both have 50, so localeCompare decides, and "Ava" comes before "Mia". The sorted pairs are Leo, Ava, Mia, and the loop collects ["Leo", "Ava", "Mia"]. The tests print such a list as values separated by spaces: Leo Ava Mia.

    Testing

    playersResult
    [["Ava", 30], ["Ben", 25], ["Cy", 40]]["Cy", "Ava", "Ben"]
    [["Mia", 50], ["Leo", 70], ["Ava", 50]]["Leo", "Ava", "Mia"]
    [["Zoe", 0]]["Zoe"]

    Common mistakes

    • Sorting by score ascending. a[1] - b[1] puts the lowest score first; the leaderboard needs b[1] - a[1]. Sorting the example [["Mia", 50], ["Leo", 70], ["Ava", 50]] that way gives Mia, Ava, Leo.
    • Skipping the tie rule. With only the score rule, tied players stay in their old order, so Mia would come before Ava.
    • Mixing up the indexes. a[0] is the name, a[1] the score. Subtracting names is reported as a type error, and at run time it gives NaN, which does not order anything.
    • Returning the pairs. The method returns names only.
    Keep going with TypeScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free