rambi
rambi

Reputation: 1259

How can I duplicate the first and last elements of a vector?

I would like to take a vector of characters and duplicate the first letter and the last one.

The only way I managed to do that is with this ugly code:

fn repeat_ends(s: &Vec<char>) -> Vec<char> {
    let mut result: Vec<char> = Vec::new();
    let first = s.first().unwrap();
    let last = s.last().unwrap();

    result.push(*first);
    result.append(&mut s.clone());
    result.push(*last);

    result
}

fn main() {
    let test: Vec<char> = String::from("Hello world !").chars().collect();

    println!("{:?}", repeat_ends(&test)); // "HHello world !!"
}

What would be a better way to do it?

Upvotes: 0

Views: 95

Answers (2)

rethab
rethab

Reputation: 8443

If it's ok to mutate the original vector, this does the job:

fn repeat_ends(s: &mut Vec<char>) {
    let first = *s.first().unwrap();
    s.insert(0, first);

    let last = *s.last().unwrap();
    s.push(last);
}

fn main() {
    let mut test: Vec<char> = String::from("Hello world !").chars().collect();
    repeat_ends(&mut test);
    println!("{}", test.into_iter().collect::<String>()); // "HHello world !!"
}

Vec::insert:

Inserts an element at position index within the vector, shifting all elements after it to the right.

This means the function repeat_ends would be O(n) with n being the number of characters in the vector. I'm not sure if there is a more efficient method if you need to use a vector, but I'd be curious to hear it if there is.

Upvotes: 2

Gurwinder Singh
Gurwinder Singh

Reputation: 39517

I am not sure if it is "better" but one way is using slice patterns:

fn repeat_ends(s: &Vec<char>) -> Vec<char> {
    match s[..] {
        [first, .. , last ] => {
            let mut out = Vec::with_capacity(s.len() + 2);
            out.push(first);
            out.extend(s);
            out.push(last);
            out
        },
        _ => panic!("whatever"), // or s.clone()
    }
}

If it can be mutable:

fn repeat_ends(s: &mut Vec<char>) {
    if let [first, .. , last ] = s[..] {
        s.insert(0, first);
        s.push(last);
    }
}

Upvotes: 3

Related Questions