从Rust向量中间开始的单循环迭代

k7fdbhmy  于 2023-10-20  发布在  其他
关注(0)|答案(2)|浏览(102)

我有一个向量的一些元素,我想从一些索引和循环周围从前面再次,而只有访问每个元素一次。
例如,从索引 2 开始,

[0, 1, 2, 3, 4, 5, 6]
       ^

我想在元素[2,3,4,5,6,0,1]上有一个迭代器(并避免在需要以这种方式运行向量的任何地方编写循环)。使用cycle()+ skip()的标准迭代似乎是一个好的开始,但它永远不会结束。
rusts标准迭代器有什么惯用的方法吗?

b4lqfgs4

b4lqfgs41#

你可以遍历两个子切片,并使用chain将它们连接到一个迭代器中:

let v = vec![0, 1, 2, 3, 4, 5, 6];
let start_index = 2;
for e in v[start_index..].iter().chain(v[..start_index].iter()) {
    println!("{}", e);
}
xxhby3vn

xxhby3vn2#

对cycle/skip组合的明显修复是添加take()来限制它:

fn cycle<T>(slice: &[T], start_pos: usize) -> impl Iterator<Item = &T> {
    slice.iter().cycle().skip(start_pos).take(slice.len())
}

另一种选择是将两个范围链接起来,甚至会更短:

fn cycle<T>(slice: &[T], start_pos: usize) -> impl Iterator<Item = &T> {
    slice[start_pos..].iter().chain(&slice[..start_pos])
}

两个版本均通过测试,例如:

let v = vec![0, 1, 2, 3, 4, 5, 6];
assert_eq!(cycle(&v, 2).copied().collect::<Vec<_>>(), vec![2, 3, 4, 5, 6, 0, 1]);

相关问题