Is it even possible to concatenate vectors in Rust? If so, is there an elegant way to do so? I have something like this:
let mut a = vec![1, 2, 3]; let b = vec![4, 5, 6]; for val in &b { a.push(val); }
Does anyone know of a better way?
56 Answers
The structure std::vec::Vec
has method append()
:
fn append(&mut self, other: &mut Vec<T>)
Moves all the elements of other
into Self
, leaving other
empty.
From your example, the following code will concatenate two vectors by mutating a
and b
:
fn main() { let mut a = vec![1, 2, 3]; let mut b = vec![4, 5, 6]; a.append(&mut b); assert_eq!(a, [1, 2, 3, 4, 5, 6]); assert_eq!(b, []); }
Alternatively, you can use Extend::extend()
to append all elements of something that can be turned into an iterator (like Vec
) to a given vector:
let mut a = vec![1, 2, 3]; let b = vec![4, 5, 6]; a.extend(b); assert_eq!(a, [1, 2, 3, 4, 5, 6]); // b is moved and can't be used anymore
Note that the vector b
is moved instead of emptied. If your vectors contain elements that implement Copy
, you can pass an immutable reference to one vector to extend()
instead in order to avoid the move. In that case the vector b
is not changed:
let mut a = vec![1, 2, 3]; let b = vec![4, 5, 6]; a.extend(&b); assert_eq!(a, [1, 2, 3, 4, 5, 6]); assert_eq!(b, [4, 5, 6]);
0I can't make it in one line. Damian Dziaduch
It is possible to do it in one line by using chain()
:
let c: Vec<i32> = a.into_iter().chain(b.into_iter()).collect(); // Consumed let c: Vec<&i32> = a.iter().chain(b.iter()).collect(); // Referenced let c: Vec<i32> = a.iter().cloned().chain(b.iter().cloned()).collect(); // Cloned let c: Vec<i32> = a.iter().copied().chain(b.iter().copied()).collect(); // Copied
There are infinite ways.
7Regarding the performance, slice::concat
, append
and extend
are about the same. If you don't need the results immediately, making it a chained iterator is the fastest; if you need to collect()
, it is the slowest:
#![feature(test)] extern crate test; use test::Bencher; #[bench] fn bench_concat___init__(b: &mut Bencher) { b.iter(|| { let mut x = vec![1i32; 100000]; let mut y = vec![2i32; 100000]; }); } #[bench] fn bench_concat_append(b: &mut Bencher) { b.iter(|| { let mut x = vec![1i32; 100000]; let mut y = vec![2i32; 100000]; x.append(&mut y) }); } #[bench] fn bench_concat_extend(b: &mut Bencher) { b.iter(|| { let mut x = vec![1i32; 100000]; let mut y = vec![2i32; 100000]; x.extend(y) }); } #[bench] fn bench_concat_concat(b: &mut Bencher) { b.iter(|| { let mut x = vec![1i32; 100000]; let mut y = vec![2i32; 100000]; [x, y].concat() }); } #[bench] fn bench_concat_iter_chain(b: &mut Bencher) { b.iter(|| { let mut x = vec![1i32; 100000]; let mut y = vec![2i32; 100000]; x.into_iter().chain(y.into_iter()) }); } #[bench] fn bench_concat_iter_chain_collect(b: &mut Bencher) { b.iter(|| { let mut x = vec![1i32; 100000]; let mut y = vec![2i32; 100000]; x.into_iter().chain(y.into_iter()).collect::<Vec<i32>>() }); }
running 6 tests test bench_concat___init__ ... bench: 27,261 ns/iter (+/- 3,129) test bench_concat_append ... bench: 52,820 ns/iter (+/- 9,243) test bench_concat_concat ... bench: 53,566 ns/iter (+/- 5,748) test bench_concat_extend ... bench: 53,920 ns/iter (+/- 7,329) test bench_concat_iter_chain ... bench: 26,901 ns/iter (+/- 1,306) test bench_concat_iter_chain_collect ... bench: 190,334 ns/iter (+/- 16,107)
3I think the best method to concatenate one or more vector is this:
let first_number: Vec<usize> = Vec::from([0]); let final_number: Vec<usize> = Vec::from([3]); let middle_numbers: Vec<usize> = Vec::from([1,2]); let numbers = [input_layer, middle_layers, output_layer].concat();
1One option is to use the extend method, which allows you to append the elements of one vector to another. Like so:
let mut a = vec![1, 2, 3]; let b = vec![4, 5, 6]; a.extend(b);
This will append the elements of b to the end of a, resulting in a vector a with the elements [1, 2, 3, 4, 5, 6].
Another way is you can use the concat function from the std::iter module to concatenate two vectors. This function takes two vectors as arguments and returns a new vector that is the concatenation of the two input vectors. Like so:
use std::iter; let a = vec![1, 2, 3]; let b = vec![4, 5, 6]; let c = iter::concat(a, b);
This will create a new vector c with the elements [1, 2, 3, 4, 5, 6].
You can also use the [..] operator to concatenate two vectors. This operator allows you to create a new vector that is the concatenation of two input vectors. Like so:
let a = vec![1, 2, 3]; let b = vec![4, 5, 6]; let c = [&a[..], &b[..]].concat();
This will create a new vector c with the elements [1, 2, 3, 4, 5, 6].
1made some fix on Mattia Samiolo's answer:
let first_number: Vec<usize> = Vec::from([0]); let final_number: Vec<usize> = Vec::from([3]); let middle_numbers: Vec<usize> = Vec::from([1, 2]); let numbers = [first_number, middle_numbers, final_number].concat(); println!("{:?}", numbers);
ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJoa2lvaWeFcX2OsJ%2BarF2ewG7Ax55km52jqXq4rdhmq6hlk6S7pK3TnqWarJViw6av06iprGWZo3qzwdKt