What Insert and RemoveAt do
Add always puts a new item at the end of a List<T>. When the item belongs somewhere else, call Insert(index, value). The item goes at index, and every item from that position on moves one place to the right.
RemoveAt(index) is the opposite. It takes out the item at index, and the items behind it move one place to the left to close the gap. In both cases the list changes in place, so the same list object now has a different length. Here is the vet's waiting line from the lesson:
List<string> pets = new List<string>(new[] {"Rex", "Milo", "Luna"});
pets.Insert(1, "Bella");
Console.WriteLine(string.Join(" ", pets));
pets.RemoveAt(2);
Console.WriteLine(string.Join(" ", pets));
It prints:
Rex Bella Milo Luna
Rex Bella Luna
The snippets use List<T>, which lives in System.Collections.Generic. In a file of your own, add using System.Collections.Generic; and using System; at the top.
Indexes change after every edit
The lesson's exercise is built around this fact. Before the insert, Milo is at index 1. After Insert(1, "Bella"), Bella is at index 1, and Milo and Luna have moved to indexes 2 and 3. That is why Milo is removed with RemoveAt(2), not RemoveAt(1). Removing index 1 would send Bella home instead.
The same rule applies to a removal: every item behind the gap gets an index one lower. When you make several edits in a row, work out the current indexes after each one.
The exercise, step by step
The list starts as Rex, Milo, Luna.
- Insert Bella at index 1. The index comes first and the value second:
pets.Insert(1, "Bella"). The list is now Rex, Bella, Milo, Luna, which is why the first printed line is 4. - Remove Milo. He is at index 2 now, so call
pets.RemoveAt(2). The list is Rex, Bella, Luna.
The complete solution:
List<string> pets = new List<string>(new[] {"Rex", "Milo", "Luna"});
pets.Insert(1, "Bella");
Console.WriteLine(pets.Count);
pets.RemoveAt(2);
Console.WriteLine(pets[0] + " " + pets[1] + " " + pets[2]);
The expected output is:
4
Rex Bella Luna
Traps to avoid
- RemoveAt versus Remove.
Remove(x)takes a value, not an index. It deletes the first item equal toxand returnstrue, or returnsfalseand changes nothing when there is no such item. With a list of numbers the two look alike and behave differently. For a list holding 10, 3, 1,RemoveAt(1)leaves 10, 1, because it removes index 1, which holds the 3.Remove(1)leaves 10, 3, because it removes the value 1. - Value first, index second.
Insert("Bella", 1)does not compile for a list of strings. For a list of numbers, a swapped call compiles and quietly does something else, so check the order. - Indexes out of range. The valid positions for
Insertrun from 0 up toCount. Inserting atCountputs the item at the end, likeAdd. Inserting beyondCount, or callingRemoveAtwith an index that is not belowCount, throws anArgumentOutOfRangeException. - Stale indexes. An index worked out before an insert or a removal may point at a different item afterwards.
Key takeaways
Insert(i, x)putsxat indexiand shifts the later items right.RemoveAt(i)deletes the item at indexiand shifts the later items left.Remove(x)searches for a value and takes no index.- Both methods change the list itself, so recompute the indexes after each edit.
