rust 如何压缩两个以上的迭代器?

mwkjh3gx  于 2022-12-04  发布在  其他
关注(0)|答案(4)|浏览(111)

是否有更直接、更易读的方法来完成以下任务:

fn main() {
    let a = [1, 2, 3];
    let b = [4, 5, 6];
    let c = [7, 8, 9];
    let iter = a.iter()
        .zip(b.iter())
        .zip(c.iter())
        .map(|((x, y), z)| (x, y, z));
}

也就是说,我怎样才能从n个迭代中构建一个迭代器,并产生n元组呢?

djp7away

djp7away1#

您可以使用crate itertools中的izip!()宏,它可以为任意多个迭代器实现此操作:

use itertools::izip;

fn main() {

    let a = [1, 2, 3];
    let b = [4, 5, 6];
    let c = [7, 8, 9];

    // izip!() accepts iterators and/or values with IntoIterator.
    for (x, y, z) in izip!(&a, &b, &c) {

    }
}

你必须在Cargo.toml中添加一个itertools依赖项,使用最新的版本。例如:

[dependencies]
itertools = "0.8"
2nbm6dog

2nbm6dog2#

您还可以使用提供的.zip创建一个宏,

$ cat z.rs
macro_rules! zip {
    ($x: expr) => ($x);
    ($x: expr, $($y: expr), +) => (
        $x.iter().zip(
            zip!($($y), +))
    )
}

fn main() {
    let x = vec![1,2,3];
    let y = vec![4,5,6];
    let z = vec![7,8,9];

    let zipped = zip!(x, y, z);
    println!("{:?}", zipped);
    for (a, (b, c)) in zipped {
        println!("{} {} {}", a, b, c);
    }
}

输出:

$ rustc z.rs && ./z
Zip { a: Iter([1, 2, 3]), b: Zip { a: Iter([4, 5, 6, 67]), b: IntoIter([7, 8, 9]), index: 0, len: 0 }, index: 0, len: 0 }
1 4 7
2 5 8
3 6 9
6yjfywim

6yjfywim3#

我希望能够对任意长的向量执行此操作,因此我必须手动实现此操作:

fn transpose_records<T: Clone>(records: &Vec<Vec<T>>) -> Vec<Vec<T>> {
    let mut transposed: Vec<Vec<T>> = vec![Vec::new(); records[0].len()];

    for record in records {
        for (index, element) in record.iter().enumerate() {
            transposed[index].push(element.clone());
        }
    }

    transposed
}
sbtkgmzw

sbtkgmzw4#

现在,您可以在没有任何外部依赖项的情况下执行以下操作:

for (inp, want) in inputs.iter().zip(wants.iter()) {
   // ...
}

此方法还支持不同的类型。

相关问题