RustArena

Step 4 of 7

Insert, remove, swap, truncate, clear

push and pop work at the end. These methods work anywhere in the vector:

fn main() {
    let mut playlist = vec!["intro", "verse", "chorus", "outro"];

    playlist.insert(1, "drums");
    println!("{:?}", playlist);

    let removed = playlist.remove(0);
    println!("removed {removed}: {:?}", playlist);

    playlist.swap(0, 2);
    println!("{:?}", playlist);

    playlist.truncate(2);
    println!("{:?}", playlist);

    playlist.extend(["bridge", "finale"]);
    println!("{:?}", playlist);

    playlist.clear();
    println!("{:?} len {}", playlist, playlist.len());
}
["intro", "drums", "verse", "chorus", "outro"]
removed intro: ["drums", "verse", "chorus", "outro"]
["chorus", "verse", "drums", "outro"]
["chorus", "verse"]
["chorus", "verse", "bridge", "finale"]
[] len 0
Method What it does
insert(i, x) puts x at index i, shifting everything after it one place right
remove(i) takes out the element at i and returns it, shifting the rest left
swap(i, j) exchanges two elements
truncate(n) keeps the first n elements, drops the rest
extend(other) appends every element of other
clear() removes everything (the capacity is kept for reuse)

What things cost

insert and remove near the front have to shift every later element, so on a vector with a million elements, remove(0) moves a million values. At the end, push/pop are cheap. If order doesn't matter, swap_remove(i) removes in constant time by moving the last element into the hole. If you need a queue (add at the back, take from the front), module 44's VecDeque does both ends cheaply.

Bad indexes panic

remove and insert check the index like v[i] does:

removal index (is 7) should be < len (is 4)
insertion index (is 9) should be <= len (is 4)

Note the <= for insert: inserting at len() is allowed and means "at the end".

Common mistake: removing inside an index loop

for i in 0..v.len() {
    if v[i] < 0 {
        v.remove(i); // shifts the rest left: the next element is skipped,
    }                // and the last indexes are now out of bounds
}

Removing changes the indexes of everything after it. To remove every element that matches a condition, use retain, which you'll meet in two steps.

Your task

Finish this playlist editor. Each input line is a command (songs are single words, indexes are always numbers):

At the end the program prints the playlist (done for you).

Challenge 2

An editor keeps a "recent files" list, most recent first. Write fn move_to_front(list: &mut Vec<String>, index: usize) that moves the file at index to the front (index 0), keeping the others in order. If index is out of range, leave the list unchanged.

Challenge 3

Write fn insert_sorted(list: &mut Vec<i32>, value: i32). The list is already sorted from smallest to largest; insert value at the right place so it stays sorted (after any equal values). Find the position with a loop, then call insert.

Previous: Looping: &v, &mut v and v Next: Sorting