Start learning free

LESSON 136 OF 677 · DICTIONARIES - CHALLENGES

Sell an Item: Update or Remove a Map Entry in Kotlin

Practice Read the full explanation

You get inventory, a HashMap 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

    KOTLIN · DICTIONARIES - CHALLENGES

    Sell An Item in Kotlin, explained

    Problem overview

    The function sellItem gets inventory, a MutableMap<String, Int> from item names to how many of each 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. The item is always a key, every count is at least 1, and the order of entries doesn't matter.

    With {"apples": 5, "pears": 2} and "apples", the apples drop to 4. With {"cups": 1, "plates": 3} and "cups", the last cup is sold, so "cups" disappears and only the plates remain. With {"pen": 1} and "pen", the map ends up empty.

    Approach

    There are two outcomes: the item stays with a smaller count, or it leaves. Work out the new count first, then decide. If it is 0, the key goes with remove. Otherwise the key is assigned the new count, which replaces the old one. Because the task guarantees the key exists, reading its count can't fail.

    Step by step

    1. Compute what is left. Read the count with inventory[item]!! and subtract 1, storing it in a val named remaining. The read has the type Int? because a key could be missing in general, and !! turns it into a plain Int. That is safe here because the task guarantees the key.
    2. Sold out? If remaining == 0, call inventory.remove(item). The key and its value both go.
    3. Otherwise update. In the else branch, set inventory[item] = remaining.
    4. Return inventory. Only the entry for item changed, or it is gone.

    The solution in Kotlin

    class Solution {
        fun sellItem(inventory: MutableMap<String, Int>, item: String): MutableMap<String, Int> {
            val remaining = inventory[item]!! - 1
            if (remaining == 0) {
                inventory.remove(item)
            } else {
                inventory[item] = remaining
            }
            return inventory
        }
    }
    

    Printing each result as sorted key: value lines (the tests' format) gives, for the three examples:

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

    Note the precedence in inventory[item]!! - 1: the !! applies to the value that was read, then the subtraction runs on the plain Int.

    Edge cases and common mistakes

    • Subtracting without removing. Writing only inventory[item] = inventory[item]!! - 1 leaves cups: 0 in the map after the last cup is sold, instead of removing the key.
    • Removing at the wrong moment. Take the item out only when the new count is 0, not whenever the count is small. A shop with 2 cups left must keep the key, with 1 cup.
    • Forgetting !!. Without it, inventory[item] - 1 doesn't compile: an Int? has no -, and the compiler says the call is prohibited on a nullable receiver.
    • Touching other entries. Only the sold item's entry changes: the plates stay at 3 in the second example.
    • A single-item map. Removing the only key gives an empty map, which is the correct answer for the third example.

    What happens to the map

    For {"cups": 1, "plates": 3} and "cups", the read gives 1, so remaining is 0. Up to that point the map is untouched and still holds both items. The if branch then calls remove("cups"), which leaves {plates=3}, and the else branch is skipped. For "apples" in the first example the count is 5, so remaining is 4, the if is skipped, and the else branch stores 4 under "apples".

    Testing

    • {"apples": 5, "pears": 2}, "apples" gives apples: 4 and pears: 2.
    • {"cups": 1, "plates": 3}, "cups" gives only plates: 3.
    • {"pen": 1}, "pen" gives an empty map.
    Keep going with Kotlin500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free