Skip to content

Vec::insert

Vec methods · Collections

Level: reference · for working programmers

One line: Put an element at index, shifting everything after it to the right.

pub fn insert(&mut self, index: usize, element: T)

Stable since 1.0.0.

O(n − index), not O(1). Every element from index onwards moves one place. insert(0, x) is therefore the expensive one: it shifts the entire vector.

Building a list front-first with insert(0, …) is quadratic. Push and reverse once instead, or use a VecDeque if both ends are hot.

index == len() is legal and appends — that is the one past-the-end index that does not panic. Anything above it panics.

Removing several elements by index has the mirror problem: the indices move under you. Go back to front, or use retain, which is one pass and cannot get it wrong.

Example

vec_insert.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.

fn main() {
    let mut v = vec!["Ada", "Cara"];
    v.insert(1, "Ben");
    println!("{v:?}");

    // index == len is the one past-the-end index that is legal: it appends.
    v.insert(v.len(), "Dana");
    println!("append via insert: {v:?}");

    // insert(0, ..) is the expensive one: every element shifts right.
    let mut v = vec![3, 4, 5];
    v.insert(0, 2);
    v.insert(0, 1);
    println!("front inserts: {v:?}");

    // O(n - index), not O(1) — the elements after `index` are all moved.
    // Building a list front-first with insert(0, ..) is quadratic; pushing
    // and reversing once is linear.
    let mut by_insert = Vec::new();
    for n in 1..=5 { by_insert.insert(0, n); }
    let mut by_push = Vec::new();
    for n in 1..=5 { by_push.push(n); }
    by_push.reverse();
    println!("{by_insert:?} == {by_push:?}: {}", by_insert == by_push);

    // index > len panics. Catching it here so the page can show the message.
    let hook = std::panic::take_hook();
    std::panic::set_hook(Box::new(|_| {}));
    let caught = std::panic::catch_unwind(|| {
        let mut v = vec![1, 2, 3];
        v.insert(9, 0);
    });
    std::panic::set_hook(hook);
    println!("insert(9, ..) into a len-3 vec panicked: {}", caught.is_err());
}

Verified output of vec_insert.rs — regenerated by tools/run_examples.py, never hand-typed.

["Ada", "Ben", "Cara"]
append via insert: ["Ada", "Ben", "Cara", "Dana"]
front inserts: [1, 2, 3, 4, 5]
[5, 4, 3, 2, 1] == [5, 4, 3, 2, 1]: true
insert(9, ..) into a len-3 vec panicked: true

See also

Vec::insert in the standard library ↗