Problem overview
The method AddIfMissing receives a shopping list items, a List<string>, and a word item. It adds item at the end of the list, but only when the list does not hold it yet. Either way, it returns the list. The list may start empty.
With ["milk", "eggs"] and "bread", the word is new and goes at the end: ["milk", "eggs", "bread"]. With the same list and "milk", it is already there, and the list stays ["milk", "eggs"]. With an empty list and "apples", the word is new, so the result is ["apples"].
Approach
Two things are needed: a way to ask "is it already in the list?" and a way to add to the end. Contains(item) answers the first with a bool, and Add(item) does the second. The task is a condition that joins them: add only when the list does not contain the word. The ! operator turns true into false and back, so the condition is !items.Contains(item).
When the word is already there, the if body is skipped and the list goes back unchanged. The empty list needs no special case: Contains on an empty list is false, so the word is added.
Step by step
- Write the guard. An
ifwhose condition is true when the item is missing:!items.Contains(item). Close its braces at once, so the next step has a place to go. - Add inside the guard.
items.Add(item)appends to the end. It runs only for a new word, so the list never gets the same word twice. - Return
itemsafter theif, whether or not anything was added.
The solution in C#
class Solution {
public List<string> AddIfMissing(List<string> items, string item) {
if (!items.Contains(item)) {
items.Add(item);
}
return items;
}
}
Running it on the three examples gives these lists, printed as words separated by spaces:
milk eggs bread
milk eggs
apples
The C# details worth knowing:
- Strings compare by content.
Containsuses equality for the item type, and for strings that means the same characters, not the same object in memory. The comparison is case-sensitive, so"Milk"and"milk"are different words. The lesson's words are all lowercase. - The list is changed in place.
List<T>is a reference type, so the method edits the caller's list and returns that same list. Calling the method does not make a copy. - The return type is a list.
Additself returns nothing (void), soreturn items.Add(item);does not compile. Return the list on its own line.
Edge cases and common mistakes
- Adding without the check. Calling
Addevery time puts a second"milk"in the list:["milk", "eggs", "milk"]. - Forgetting the
!.if (items.Contains(item))adds only words that are already there. The list never grows. - Returning inside the
ifonly. If the return sits in the braces, the method has no value to give when the word was already there, and C# refuses to compile it. - An empty list. It works without extra code. Checking
items.Count == 0separately is not needed. - A different case. Matching is exact, so lists that mix
"Milk"and"milk"need the words made lowercase first. The lesson's words are always lowercase.
Testing
["milk", "eggs"],"bread"gives["milk", "eggs", "bread"].["milk", "eggs"],"milk"gives["milk", "eggs"].[],"apples"gives["apples"].["tea"],"tea"gives["tea"].
