Start learning free

LESSON 112 OF 674 · ARRAYS I

Insert and Remove at a Position in a C# List

Lesson Read the full explanation

TL ; DR:

Insert(i, x) puts x at index i. Use RemoveAt(i) to take out the item at index i. The other items move to make room or to close the gap.


List<string> colors = new List<string>(new[] {"red", "green", "blue"});

colors.Insert(1, "pink");
// colors is now [red, pink, green, blue]

colors.RemoveAt(0);
// colors is now [pink, green, blue]


Full lesson:

Add puts an item at the end. To put one anywhere else in a List, use Insert(i, x). The items from index i on move one place to the right.

List<string> pets = new List<string>(new[] {"Rex", "Milo"});

pets.Insert(0, "Luna");
// pets is now [Luna, Rex, Milo]

You met RemoveAt(i) in the last lesson. It takes out the item at index i. The items after it move one place to the left.

pets.RemoveAt(0);
// pets is now [Rex, Milo]

Watch the indexes. After an insert or a removal, the items behind that spot have new indexes.

Don't mix up RemoveAt and Remove. Remove(x) takes out the first item equal to x. It doesn't take an index.


Your task

pets holds the pets waiting at the vet, in order.

Bella has an appointment, so she goes second, at index 1. Then Milo goes home. Take him out of the line.

The code below prints how many pets wait once Bella is in. At the end, it prints the pets left.

Expected output:

4
Rex Bella Luna
STEP 1 OF 2
    Ctrl + Enter to check

    C# · ARRAYS I

    Array Insert Remove in C#, explained

    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.

    1. 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.
    2. 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 to x and returns true, or returns false and 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 Insert run from 0 up to Count. Inserting at Count puts the item at the end, like Add. Inserting beyond Count, or calling RemoveAt with an index that is not below Count, throws an ArgumentOutOfRangeException.
    • Stale indexes. An index worked out before an insert or a removal may point at a different item afterwards.

    Key takeaways

    • Insert(i, x) puts x at index i and shifts the later items right.
    • RemoveAt(i) deletes the item at index i and 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.
    Keep going with C#500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free