Start learning free

LESSON 266 OF 677 · TUPLES, SORTING & BUILT-INS

Oldest Pet in Scala: Looping Over Tuples

Practice Read the full explanation

You get an ArrayBuffer of pets, pets. Each pet is a pair: its name and its age, like ("Rex", 4).

Return the name of the oldest pet.

Several pets may share the oldest age. Then return the one that comes first in pets.

The starter code shows how your language holds a pair.

 

Example 1:

Input: pets = [("Rex", 4), ("Bella", 7), ("Max", 2)]
Output: "Bella"
Explanation: Bella is 7.
Rex and Max are younger.

Example 2:

Input: pets = [("Luna", 3), ("Coco", 9), ("Milo", 9)]
Output: "Coco"
Explanation: Coco and Milo are both 9.
Coco comes first in the list.

Example 3:

Input: pets = [("Kiki", 0)]
Output: "Kiki"
Explanation: Kiki is the only pet.

 

Constraints:

  • pets has at least one pet.
  • Every age is a whole number from 0 to 30.
  • Each name is a capital letter followed by lowercase letters, like "Rex".
STEP 1 OF 5
    Ctrl + Enter to check

    SCALA · TUPLES, SORTING & BUILT-INS

    Oldest Pet in Scala, explained

    Problem overview

    oldestPet gets an ArrayBuffer[(String, Int)] called pets. Each pet is a tuple of its name and its age, like ("Rex", 4). The function returns the name of the oldest pet. When several pets share the oldest age, it returns the one that comes first in the list.

    • [("Rex", 4), ("Bella", 7), ("Max", 2)] gives Bella.
    • [("Luna", 3), ("Coco", 9), ("Milo", 9)] gives Coco, because Coco and Milo are both 9 and Coco is first.
    • [("Kiki", 0)] gives Kiki.

    Approach

    Keep the oldest pet seen so far in a variable called oldest, and walk through the list once. A pet replaces oldest only when it is older. Because the comparison is strictly greater, a pet of the same age never replaces the one already held, which keeps the first one on a tie.

    The variable holds the whole tuple, not just the age. That way the name comes along, and the function can return it after the loop.

    This is a single pass over the list with one extra variable, so there is nothing to sort. Sorting the pets by age would also work, but it does more work than the question needs.

    Step by step

    1. Declare oldest with var, starting with the first pet, pets(0). Before the loop looks at anything else, the first pet is the oldest one seen.
    2. Loop with pet <- pets.
    3. Inside, check whether pet._2 > oldest._2. A pet's age is its _2.
    4. If it is older, set oldest = pet.
    5. After the loop, return oldest._1, the name.

    The solution in Scala

    class Solution {
        def oldestPet(pets: ArrayBuffer[(String, Int)]): String = {
            var oldest = pets(0)
            for (pet <- pets) {
                if (pet._2 > oldest._2) {
                    oldest = pet
                }
            }
            return oldest._1
        }
    }
    

    The type of oldest is (String, Int), inferred from pets(0), so assigning pet to it is allowed. The loop starts at the first pet again, which compares it with itself and changes nothing.

    The loop could also unpack each pet, as in for ((name, age) <- pets), but then you would need a second variable for the best name and another for the best age. Keeping the whole tuple means one variable.

    Tracing the tie

    Printing pet and oldest on each pass for the second example shows why the first of two equal ages wins:

    pet=(Luna,3) oldest=(Luna,3)
    pet=(Coco,9) oldest=(Coco,9)
    pet=(Milo,9) oldest=(Coco,9)
    

    Milo is 9, the same as Coco, so 9 > 9 is false and Coco stays.

    Another way

    Scala collections also have maxBy. pets.maxBy(p => p._2)._1 gives Coco for the same list, because maxBy returns the first element with the largest value. Writing the loop yourself first shows what that one call does.

    Testing

    [("Rex", 4), ("Bella", 7), ("Max", 2)]    Bella
    [("Luna", 3), ("Coco", 9), ("Milo", 9)]   Coco
    [("Kiki", 0)]                             Kiki
    

    Edge cases and common mistakes

    • Using >=. On the second example, the loop would replace Coco with Milo, and the function would return Milo. The lesson wants the first of the tied pets.
    • Returning the tuple. The function returns a String, so return oldest._1, not oldest.
    • Mixing up _1 and _2. The name is _1 and the age is _2. Comparing names with > compiles for strings, but it compares alphabetically.
    • Starting with an age of 0. An age can be 0, as with Kiki, so a made-up starting value can hide a real pet. Starting from pets(0) avoids that.
    Keep going with Scala500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free