Reputation: 11
I can copy a vector from a slice like so:
let mut my_vector = Vec::from_iter(other_vector[n..n+5].iter().cloned());
Is there a way to copy a vector so that I wrap around the end? e.g., for the vector [1,2,3,4,5] I could copy [5,1,2]
std::iter::Cycle provides a cycle iterator but I'm not sure how to take advantage of it.
Upvotes: 0
Views: 557
Reputation: 302
With a functional programming approach, you can map through index iterator from 0 to 3 and then collect corresponding vector values (got using modulo concept).
fn main(){
let n = 4;
let other_vector = vec![1, 2, 3, 4, 5];
let modulo = other_vector.len();
let l = 3;
let my_vector: Vec<i32> = (0..l).into_iter().map(|i| other_vector[(n+i)%modulo]).collect();
dbg!(my_vector);
}
I do a benchmark to compare the 2 methods std::iter::Cycle (@Prime_Aqasix response) and map/collect method
#![feature(test)]
extern crate test;
use test::Bencher;
use std::iter::FromIterator;
fn test1(other_vector:&Vec<i32>) {
let n = 4;
let my_vector = Vec::from_iter(other_vector.iter().cycle().skip(n).take(3).cloned());
dbg!(my_vector);
}
fn test2(other_vector:&Vec<i32>) {
let n = 4;
let modulo = other_vector.len();
let l = 3;
let my_vector: Vec<i32> = (0..l).into_iter().map(|i| other_vector[(n+i)%modulo]).collect();
dbg!(my_vector);
}
#[bench]
fn bench_test1(bencher: &mut Bencher) {
let other_vector: Vec<i32> = (0..10000).map(|v| v + 1000).collect();
bencher.iter(|| test1(&other_vector));
}
#[bench]
fn bench_test2(bencher: &mut Bencher) {
let other_vector: Vec<i32> = (0..10000).map(|v| v + 1000).collect();
bencher.iter(|| test2(&other_vector));
}
To execute, you just have to run "cargo bench" command. These are my results:
First test:
running 2 tests
test bench_test1 ... bench: 686 ns/iter (+/- 487)
test bench_test2 ... bench: 576 ns/iter (+/- 398)
test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured; 0 filtered out; finished in 11.78s
Second test:
running 2 tests
test bench_test1 ... bench: 696 ns/iter (+/- 755)
test bench_test2 ... bench: 622 ns/iter (+/- 419)
test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured; 0 filtered out; finished in 13.32s
Third test:
running 2 tests
test bench_test1 ... bench: 638 ns/iter (+/- 537)
test bench_test2 ... bench: 494 ns/iter (+/- 529)
test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured; 0 filtered out; finished in 4.76s
Functional programming approach is more likely speedup the copy. This is a good alternative to std::iter::cycle
Upvotes: 0
Reputation: 4133
You can use std::iter::Cycle
directly after you converted it to an iterator, and then use skip
to get to the place you want in the iterator, before using take
to take the number of elements you want in the new iterator.
fn main() {
let n = 4;
let other_vector = vec![1,2,3,4,5];
let my_vector = Vec::from_iter(other_vector.iter().cycle().skip(n).take(3).cloned());
dbg!(my_vector);
}
Upvotes: 0