如何使用迭代器逐级遍历集合中的两个元素?



假设我们有一个向量:

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

遍历元素的最佳和最短方法是什么,以便在第一次迭代中我收到(1, 2)的元组,并在下一次迭代中收到(2, 3),直到没有元素,因此不产生(3, None)或类似的东西?似乎a.chunks(2)有点不同,它每两个步进,而我需要在一个集合中每两个连续的元素一步进。

有多种方法可以这样做:

使用标准库:

.zip

let result = a.iter()
.zip(a.iter().skip(1))
.inspect(|(a, b)| println!("a: {}, b: {}", a, b))
.collect::<Vec<_>>();

.windows

let result = a.windows(2)
.inspect(|w| println!("a: {}, b: {}", w[0], w[1]))
.collect::<Vec<_>>();
值得注意的是,如果这很重要,windows()在子片上迭代,因此与上面的方法不同,collect()在这种情况下不会给您一个元组的Vec

使用Itertoolscrate:

.tuple_windows

use itertools::Itertools;
let result = a.iter()
.tuple_windows()
.inspect(|(a, b)| println!("a: {}, b: {}", a, b))
.collect::<Vec<_>>();

以上所有方法将打印以下内容:

a: 1, b: 2
a: 2, b: 3

作为奖励,Itertools最近也有一个.circular_tuple_windows(),它通过包含最后一个(3)和第一个(1)元素来执行额外的迭代:

use itertools::Itertools;
let result = a.iter()
.circular_tuple_windows()
.inspect(|(a, b)| println!("a: {}, b: {}", a, b))
.collect::<Vec<_>>();
a: 1, b: 2
a: 2, b: 3
a: 3, b: 1

您也可以使用chunks()。现在元素将不会重叠。

fn main() {
let vec = vec![1, 2, 4, 5, 8, 9];
let new_thing = vec.chunks(2).map(|x| println!("{} and {}", x[0],
x[1])).collect::<Vec<_>>();
}
1 and 2
4 and 5
8 and 9

使用仅限夜间(截至2021年初)的array_windows功能,您可以遍历长度为2的数组引用:

for [a, b] in arg.array_windows() {
println!("a: {}, b: {}", a, b);
}

游乐场

注意使用的是片模式[a, b],而不是元组模式(a, b)

在稳定状态下,你可以用windowstry_into实现同样的事情,但它不那么干净:

use std::convert::TryInto;
for s in arg.windows(2) {
let [a, b]: [i32; 2] = s.try_into().unwrap();
println!("a: {}, b: {}", a, b);
}

最新更新