Start learning free

LESSON 127 OF 679 · ARRAYS - CHALLENGES

Move to Front in Rust: Using remove and insert

Practice Read the full explanation

You get a to-do list items, a Vec of strings, and a number index. Return the list with the item at index moved to the front.

Take the item out of its place and put it at index 0. The other items keep their order.

 

Example 1:

Input: items = ["wash", "shop", "cook", "read"], index = 2
Output: ["cook", "wash", "shop", "read"]
Explanation: The item at index 2 is "cook". It moves to the front.
Then "wash" and "shop" move one place to the right.

Example 2:

Input: items = ["tea", "coffee"], index = 0
Output: ["tea", "coffee"]
Explanation: The item at index 0 is already at the front.
Nothing changes.

Example 3:

Input: items = ["call", "pay", "call", "walk"], index = 2
Output: ["call", "call", "pay", "walk"]
Explanation: The "call" at index 2 moves to the front.
The other "call" and "pay" move one place to the right.

 

Constraints:

  • items has 1 to 10 words.
  • index is from 0 to the length of items minus 1.
  • Every word is made of lowercase English letters.
  • The same word may appear more than once.
STEP 1 OF 3
    Ctrl + Enter to check

    RUST · ARRAYS - CHALLENGES

    Move To Front in Rust, explained

    Problem overview

    The function move_to_front receives a to-do list items, a vector of strings, and an index. It returns the list with the item at index taken out of its place and put at index 0. All the other items keep their relative order.

    For ["wash", "shop", "cook", "read"] and index = 2, the item is "cook". It moves to the front, and "wash" and "shop" shift one place to the right: ["cook", "wash", "shop", "read"]. With index = 0 the item is already first and nothing changes.

    Approach

    A Vec has two methods that do exactly the two halves of the job. remove(i) takes the item out of position i, closes the gap, and hands the item back. insert(0, x) puts x at the front and shifts everything else one place right. Doing them in that order moves the item without disturbing anyone else.

    Step by step

    1. The signature says mut items, which lets the function change the vector it received. Call items.remove(index) and store what it returns in item. Now the vector is one shorter, and item holds the removed string by itself.
    2. Call items.insert(0, item). The string moves into the vector, and every other item shifts one place right.
    3. End the function with items, without a semicolon.

    The solution in Rust

    impl Solution {
        fn move_to_front(mut items: Vec<String>, index: usize) -> Vec<String> {
            let item = items.remove(index);
            items.insert(0, item);
            items
        }
    }
    

    Two Rust details matter. The mut in the parameter list is what allows remove and insert to run; it doesn't change what callers pass. And item is a String, so insert takes ownership of it: after that line you can't use item again. That is why the code never needs a copy of the string.

    Following one call

    Take ["wash", "shop", "cook", "read"] and index = 2. After remove(2), item is "cook" and the list is ["wash", "shop", "read"]. After insert(0, item), the list is ["cook", "wash", "shop", "read"]. Each method shifts the items behind its position by one place, and the two shifts happen on different parts of the list, so the other items end up in their original relative order.

    Why not swap

    Swapping the item with the one at index 0 would put it in front, but it would also send the old first item to the item's old place, so the others would not keep their order. For ["wash", "shop", "cook", "read"], a swap would give ["cook", "shop", "wash", "read"]. The task wants the others to stay in order, and only remove followed by insert guarantees that.

    Edge cases and common mistakes

    • Index 0. The item is removed from the front and inserted at the front again, so the list comes back as it was.
    • Duplicate words. The function moves the item at the given position, not the first matching word. With ["call", "pay", "call", "walk"] and index 2, the second "call" moves, giving ["call", "call", "pay", "walk"].
    • Inserting before removing. Doing insert(0, ...) first shifts everything right, so the original index no longer points at the item.
    • A bad index. An index at or past the length would panic in remove. The constraints keep it inside the list.

    Testing

    Results from running the function:

    • ["wash", "shop", "cook", "read"], index = 2 gives ["cook", "wash", "shop", "read"].
    • ["tea", "coffee"], index = 0 gives ["tea", "coffee"].
    • ["call", "pay", "call", "walk"], index = 2 gives ["call", "call", "pay", "walk"].
    Keep going with Rust500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free