Problem overview
The method sellItem receives inventory, an object that maps item names to how many of each item a shop has, and the item a customer just bought. It sells one item and returns the updated object. The count of item drops by 1, and when it reaches 0 the item is removed from the object. The order of the entries does not matter.
The constraints are friendly: item is always a key of inventory, every count is at least 1, and item names are single lowercase words. So you never have to handle a missing item or a count of 0 on the way in.
The examples:
- Selling
"apples"from{"apples": 5, "pears": 2}gives{"apples": 4, "pears": 2}. - Selling
"cups"from{"cups": 1, "plates": 3}gives{"plates": 3}. The last cup is sold, so the key goes. - Selling
"pen"from{"pen": 1}gives{}.
Approach
Every sale lowers a count by 1. What happens next depends on what is left. If some are left, store the new count. If none are, the entry should not stay with a 0: delete it. That is one decision with two branches, so an if and an else fit.
Work out the count after the sale first, in a variable. Then both branches can use it, and the test reads clearly.
Step by step
- Compute how many are left after the sale: the count of
itemminus 1, in a variable namedremaining, declared withlet. Readinginventory[item]is safe because the item is always a key with a count of at least 1. - Write an
ifthat checks whetherremainingis 0. Its body deletesitemfrominventorywith thedeleteoperator, which removes the key and its value. - Add an
elsebranch whose body storesremainingunder the keyitem. Some are still left, so the item stays with its new count. - After the
else, returninventory. Only the entry ofitemchanged, or it is gone.
The solution in JavaScript
class Solution {
sellItem(inventory, item) {
let remaining = inventory[item] - 1;
if (remaining == 0) {
delete inventory[item];
} else {
inventory[item] = remaining;
}
return inventory;
}
}
Details worth knowing
The test uses ==, which compares loosely. With two numbers it behaves like ===, and in everyday JavaScript === is the safer habit. Both work here, because remaining is always a number.
The delete operator removes the whole entry. Setting the value to undefined would leave the key behind, and setting it to 0 would leave a key with a count of 0, so the shop would still list an item it no longer has.
The method changes the object it was given and returns that same object.
Testing
Running the method on the three examples and printing each result with JSON.stringify gives:
{"apples":4,"pears":2}
{"plates":3}
{}
Edge cases and common mistakes
- Leaving a zero behind. Always writing
inventory[item] = remainingturns the last cup into{"cups":0}. The object still has one key, and it should be empty. - Deleting too early. If you delete first and read the count afterwards, the count is gone. Compute
remainingbefore theif. - Setting undefined. Assigning
undefinedto a key leaves it in the object:"cups" in invstaystrue. - Using the old count. Testing
inventory[item]against 0 never fires, because counts start at 1 or more. Test the number left after the sale.
