Start learning free

LESSON 124 OF 677 · ARRAYS - CHALLENGES

Add If Missing in Scala

Practice Read the full explanation

You get a shopping list items, an ArrayBuffer of strings, and a word item. Add item at the end only when it isn't in the list yet. Return the list.

When item is already there, the list stays as it is. The list may start empty.

 

Example 1:

Input: items = ["milk", "eggs"], item = "bread"
Output: ["milk", "eggs", "bread"]
Explanation: The word "bread" is not in the list yet.
It goes at the end.

Example 2:

Input: items = ["milk", "eggs"], item = "milk"
Output: ["milk", "eggs"]
Explanation: The word "milk" is already there.
Nothing is added.

Example 3:

Input: items = [], item = "apples"
Output: ["apples"]
Explanation: The list is empty, so "apples" is new.
It becomes the only item.

 

Constraints:

  • items has 0 to 9 words: it may be empty.
  • item and every word in items are made of lowercase English letters.
STEP 1 OF 3
    Ctrl + Enter to check

    SCALA · ARRAYS - CHALLENGES

    Add If Missing in Scala, explained

    Problem overview

    The method addIfMissing gets a shopping list items, an ArrayBuffer[String], and a word item. It adds item at the end only when it is not in the list yet, and returns the list. The list may start empty.

    For ["milk", "eggs"] and "bread", the word is new, so the result is ["milk", "eggs", "bread"]. For the same list and "milk", the word is already there and the list stays ["milk", "eggs"]. For an empty list and "apples", the result is ["apples"].

    Approach

    Ask first, then act. items.contains(item) says whether the word is there. You want to act when it is not, so put ! in front. Inside the if, items += item appends the word. Without the check, += adds the word every time, and ["milk"] becomes ["milk", "milk"].

    Step by step

    1. Write the condition: !items.contains(item) is true exactly when the word is missing. Open the block with { and close it with }.
    2. Add the word inside it with +=, which appends at the end.
    3. After the if, return items. When the word was already there, the list comes back as it was.

    Why not just add it?

    A plain items += item would always append, so a list that already has "milk" would end up with ["milk", "milk"]. A list that never holds the same word twice is the point of the task, as in a shopping list or a guest list. The check costs one line and keeps the list free of repeats. Note that the check looks at the whole list, not only the last item: contains searches every position, so a word near the front is found as well.

    The solution in Scala

    class Solution {
        def addIfMissing(items: ArrayBuffer[String], item: String): ArrayBuffer[String] = {
            if (!items.contains(item)) {
                items += item
            }
            return items
        }
    }
    

    Notes on the Scala:

    • items += item on a mutable ArrayBuffer changes the buffer itself. The same buffer is returned.
    • The if has no else. When the word is present, nothing happens and the method goes straight to the return.
    • contains compares whole words and is case-sensitive, so "Milk" would count as new next to "milk". The constraints say every word is lowercase.

    Edge cases and common mistakes

    • An empty list. contains is false, so the word is added.
    • Forgetting !. Then the word is added only when it is already there, the opposite of the task.
    • Returning only inside the if. If the return sits inside the braces, the other path has no value to give, and the compiler reports a type mismatch: found Unit, required ArrayBuffer[String]. Return after the if.

    The method both changes the buffer and returns it. A caller can keep using the buffer it passed in, or use the returned value: they are the same object, and both show the new word.

    Another way

    Since an if is an expression in Scala, the method can also be written as one line: if (items.contains(item)) items else items += item. Both branches give the buffer, so the whole expression is the result. For ["milk"] and "milk" it gives ArrayBuffer(milk), and for "tea" it gives ArrayBuffer(milk, tea). The longer form is easier to read while you are learning.

    Testing

    [milk, eggs], "bread"  ->  milk eggs bread
    [milk, eggs], "milk"   ->  milk eggs
    [], "apples"           ->  apples
    
    Keep going with Scala500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free