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

Single cyclic iteration from middle of rust vector

我有一个包含一些元素的向量,我想从某个索引开始迭代并再次从前面开始循环,同时只访问每个元素一次。

例如。从索引 2,

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

我想要一个遍历元素 [2, 3, 4, 5, 6, 0, 1] 的迭代器(并避免在我需要 运行 通过向量的任何地方写一个循环). cycle() + skip() 的标准迭代似乎是一个好的开始,但它永远不会结束。

Rusts 标准迭代器有什么惯用的方法吗?

您可以迭代两个子切片,并使用 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);
}

您的 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]);