Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to repeat the elements in a vector in Rust?

Tags:

vector

rust

I found this way, but it seems too verbose for such a common action:

fn double_vec(vec: Vec<i32>) -> Vec<i32> {
    let mut vec1 = vec.clone();
    let vec2 = vec.clone();

    vec1.extend(vec2);

    vec1
}

I know that in JavaScript it could be just arr2 = [...arr1, ...arr1].

like image 622
Дмитрий Рыбин Avatar asked Dec 01 '17 20:12

Дмитрий Рыбин


3 Answers

You can use the concat method for this, it's simple:

fn double_vec(v: Vec<i32>) -> Vec<i32> {
    [&v[..], &v[..]].concat()
}

Unfortunately we have to make the vectors slices explicitly (here &v[..]); but otherwise this method is good because it allocates the result to the needed size directly and then does the copies.

like image 113
bluss Avatar answered Oct 24 '22 01:10

bluss


Since Rust 1.53, Vec::extend_from_within makes it possible to more efficiently double a vector:

fn double_vec(vec: &mut Vec<i32>) {
    vec.extend_from_within(..);
}
like image 41
avl_sweden Avatar answered Oct 24 '22 01:10

avl_sweden


"Doubling a vector" isn't something that's really done very often so there's no shortcut for it. In addition, it matters what is inside the Vec because that changes what operations can be performed on it. In this specific example, the following code works:

let x = vec![1, 2, 3];

let y: Vec<_> = x.iter().cycle().take(x.len() * 2).collect();

println!("{:?}", y); //[1, 2, 3, 1, 2, 3]

The cycle() method requires that the items in the Iterator implement the Clone trait so that the items can be duplicated. So if the items in your Vec implement Clone, then this will work. Since immutable references (&) implement Clone, a Vec<&Something> will work but mutable references (&mut) do not implement Clone and thus a Vec<&mut Something> will not work.

Note that even if a type does not implement Clone, you can still clone references to that type:

struct Test;

fn test_if_clone<T: Clone>(_x: T) {}

fn main() {
    let x = Test;

    test_if_clone(x); //error[E0277]: the trait bound `Test: std::clone::Clone` is not satisfied

    let y = &x;

    test_if_clone(y); //ok
}
like image 34
Wesley Wiser Avatar answered Oct 24 '22 01:10

Wesley Wiser