Start learning free

LESSON 124 OF 677 · ARRAYS - CHALLENGES

Add an Item to a List Only If Missing in Kotlin

Practice Read the full explanation

You get a shopping list items, an ArrayList 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

    KOTLIN · ARRAYS - CHALLENGES

    Add If Missing in Kotlin, explained

    Problem overview

    The function addIfMissing gets a shopping list items (a MutableList<String>) and a word item. It adds item at the end only when the list doesn't hold it yet, and returns the list. When the word is already there, the list stays as it is. The list may be empty.

    With ["milk", "eggs"] and "bread", the answer is ["milk", "eggs", "bread"]. With "milk" the list stays ["milk", "eggs"]. With an empty list and "apples", the answer is ["apples"].

    Approach

    Ask the list whether it holds the word, and add only when the answer is no. Kotlin's !in does exactly that: item !in items is true when no entry equals item, and it is true for an empty list. The check compares by content, so a different string object with the same letters counts as present.

    Step by step

    1. Test for absence. An if with the condition item !in items, and its closing brace written right away.
    2. Add inside it. items.add(item) puts the word at the end. It only runs for a new word.
    3. Return items after the if, so both outcomes return the list.

    The solution in Kotlin

    class Solution {
        fun addIfMissing(items: MutableList<String>, item: String): MutableList<String> {
            if (item !in items) {
                items.add(item)
            }
            return items
        }
    }
    

    On the three examples it gives (values separated by spaces):

    milk eggs bread
    milk eggs
    apples
    

    The function changes the list it receives and returns that same list. Putting the return inside the if would leave the function without a result when the word is already present, and Kotlin would reject the code, so keep it after the closing brace.

    Another way

    The !in operator is short for a call to contains, so the condition can also be written !items.contains(item):

    if (!items.contains(item)) {
        items.add(item)
    }
    

    It behaves the same way: for ["milk", "eggs"] and "milk" the list stays [milk, eggs]. The !in form reads closer to plain English, so the lesson uses it.

    How the check works

    The list compares the word with its entries one by one, from the first, and stops at the first match. For a list of up to nine words that is instant. It also means the function doesn't remove duplicates that were already in the list: it only avoids creating a new one. If the list already held two "milk" entries, they would both stay.

    Edge cases and common mistakes

    • Empty list. Nothing is in it, so the word is added. No special case is needed.
    • Adding without the check. items.add(item) alone would put a second "milk" in the list.
    • Reversing the condition. With item in items the word is added only when it is already there.
    • Case. The words are lowercase, so "Milk" doesn't come up here, but in general "Milk" and "milk" are different words.

    Calling it several times

    Because the function keeps what it adds, calling it again with the same word changes nothing. Starting from an empty list and offering "tea", "tea" and "jam" in turn leaves [tea, jam]: the second "tea" finds the first one and is skipped.

    Testing

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