Start learning free

LESSON 136 OF 677 · DICTIONARIES - CHALLENGES

Sell an Item in Scala

Practice Read the full explanation

You get inventory, a mutable.Map from item names to how many of each item a shop has. You also get the item a customer just bought.

Sell one item and return the updated dictionary.

The count of item drops by 1. When it reaches 0, remove item from the dictionary. The order of the entries doesn't matter.

 

Example 1:

Input: inventory = {"apples": 5, "pears": 2}, item = "apples"
Output: {"apples": 4, "pears": 2}
Explanation: One apple is sold, so 5 - 1 = 4 apples are left.

Example 2:

Input: inventory = {"cups": 1, "plates": 3}, item = "cups"
Output: {"plates": 3}
Explanation: The last cup is sold. No cups are left, so "cups" is removed.

Example 3:

Input: inventory = {"pen": 1}, item = "pen"
Output: {}
Explanation: The only pen is sold. Nothing is left in the shop.

 

Constraints:

  • item is always a key of inventory.
  • Every count is at least 1.
  • Item names are single lowercase words.
STEP 1 OF 4
    Ctrl + Enter to check

    SCALA · DICTIONARIES - CHALLENGES

    Sell An Item in Scala, explained

    Problem overview

    The method sellItem gets inventory, a scala.collection.mutable.Map[String, Int] from item names to how many of each item a shop has, and the item a customer just bought. It sells one: the count of item drops by 1, and when it reaches 0 the item is removed from the map. It returns the updated map, and the order of the entries doesn't matter.

    For {"apples": 5, "pears": 2} and "apples", apples drop to 4. For {"cups": 1, "plates": 3} and "cups", the last cup is sold, so "cups" disappears and only plates remain. For {"pen": 1} and "pen", the map ends up empty. The constraints promise that item is a key and its count is at least 1.

    Approach

    Work out the count after the sale first. If it is 0, the item is sold out and its key must go, because a key with a count of 0 would still show up as "in stock" to a contains check. Otherwise the key stays with the smaller count. Two outcomes, so an if and an else.

    Step by step

    1. Compute the count left: inventory(item) - 1, stored in a val named remaining. Reading with parentheses is safe, since item is always a key.
    2. If remaining == 0, call inventory.remove(item). Key and value both go.
    3. Otherwise, in an else branch, set inventory(item) = remaining.
    4. Return inventory. Only the entry of item changed, or it is gone.

    The solution in Scala

    class Solution {
        def sellItem(inventory: scala.collection.mutable.Map[String, Int], item: String): scala.collection.mutable.Map[String, Int] = {
            val remaining = inventory(item) - 1
            if (remaining == 0) {
                inventory.remove(item)
            } else {
                inventory(item) = remaining
            }
            return inventory
        }
    }
    

    Details on the Scala:

    • inventory(item) reads the count and throws NoSuchElementException for a missing key. The constraints rule that out here; in other code you would check with contains or use getOrElse.
    • remove returns an Option with the old stored value. When the last cup is removed that is Some(1), the count before the sale. The method ignores it.
    • The two branches of the if do different things and neither gives a value the method uses, so the branches are just statements. The return comes after both.

    A trace

    Take {"apples": 5, "pears": 2} and "apples". inventory("apples") - 1 is 4, so remaining is 4. It isn't 0, so the else branch runs and inventory("apples") becomes 4; "pears" is never touched. Now take {"cups": 1, "plates": 3} and "cups". Here remaining is 0, so remove("cups") runs, and the map keeps only "plates". In the third example the map becomes empty, and isEmpty on it is true.

    The reason to remove instead of leaving a 0 is what the map means. A key with a count of 0 still answers true to contains and still adds to size, so a shop that had sold out would look as if it stocked cups. Removing the key keeps the map equal to the shop's real shelves.

    Running it

    Results for the three examples, as key: value lines sorted by key, the way the lesson's tests print them:

    apples: 4
    pears: 2
    
    plates: 3
    
    (nothing: the map is empty)
    

    Edge cases and common mistakes

    • Keeping a zero. Writing inventory(item) = remaining in every case leaves "cups" -> 0 in the map. The task wants the key removed.
    • Comparing the wrong number. The test is on the count after the sale. Testing the old count against 0 never fires, because every count is at least 1.
    • Selling from a count of 1 in a bigger map. Other entries are untouched: only the entry of item changes.
    Keep going with Scala500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free