You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust中用迭代器实现数组i与i+1位置元素的特定元组遍历?

使用Rust迭代器替代for循环收集相邻元素元组

我在Rust Playground中编写了一个示例代码,用来遍历Person数组,收集索引i处Person的firstname与索引i+1处Person的surname组成的元组。当前通过for循环可以实现这个功能,但我希望改用iter()迭代器来实现,方便后续使用collect()或fold等方法,而非使用for循环。请问该如何实现?

原代码如下:

#[derive(Clone)]
pub struct Person {
    pub firstname: Vec<u8>,
    pub surname: Vec<u8>,
}

fn main() {
    let p0 = Person { firstname: vec![0u8; 5], surname: vec![1u8; 5], };
    let p1 = Person { firstname: vec![2u8; 7], surname: vec![3u8; 2], };
    let p2 = Person { firstname: vec![4u8; 8], surname: vec![5u8; 8], };
    let p3 = Person { firstname: vec![6u8; 3], surname: vec![7u8; 1], };
    let people = [p0, p1, p2, p3];
    
    for i in 0..people.len() {
        if i + 1 < people.len() {
            println!( "{:?}", (people[i].firstname.clone(), people[i + 1].surname.clone()) )
        }
    }
}

方法一:使用windows(2)获取相邻元素窗口

Rust的切片迭代器提供了windows(n)方法,它会返回一个迭代器,每次生成包含n个连续元素的不可变切片。对于你的需求,我们可以用windows(2)来获取每一对相邻的Person元素,然后从切片中取出第一个元素的firstname和第二个元素的surname:

#[derive(Clone)]
pub struct Person {
    pub firstname: Vec<u8>,
    pub surname: Vec<u8>,
}

fn main() {
    let p0 = Person { firstname: vec![0u8; 5], surname: vec![1u8; 5], };
    let p1 = Person { firstname: vec![2u8; 7], surname: vec![3u8; 2], };
    let p2 = Person { firstname: vec![4u8; 8], surname: vec![5u8; 8], };
    let p3 = Person { firstname: vec![6u8; 3], surname: vec![7u8; 1], };
    let people = [p0, p1, p2, p3];
    
    // 使用windows(2)遍历相邻元素对
    let tuples = people.windows(2)
        .map(|window| {
            // window是&[Person; 2]类型,取出第一个和第二个元素
            (window[0].firstname.clone(), window[1].surname.clone())
        })
        .collect::<Vec<_>>();
    
    // 打印结果,和原for循环一致
    for tuple in tuples {
        println!("{:?}", tuple);
    }
}

这种方法的优势是语义非常清晰,直接表达“处理每一组相邻的2个元素”,适合需要处理连续多个元素的场景。


方法二:使用zip配对原迭代器与跳过首元素的迭代器

另一种方式是将原数组的迭代器和跳过第一个元素的迭代器进行zip操作,这样每一对元素就是原数组中索引i和i+1的元素:

#[derive(Clone)]
pub struct Person {
    pub firstname: Vec<u8>,
    pub surname: Vec<u8>,
}

fn main() {
    let p0 = Person { firstname: vec![0u8; 5], surname: vec![1u8; 5], };
    let p1 = Person { firstname: vec![2u8; 7], surname: vec![3u8; 2], };
    let p2 = Person { firstname: vec![4u8; 8], surname: vec![5u8; 8], };
    let p3 = Person { firstname: vec![6u8; 3], surname: vec![7u8; 1], };
    let people = [p0, p1, p2, p3];
    
    // 配对原迭代器和跳过第一个元素的迭代器
    let tuples = people.iter()
        .zip(people.iter().skip(1))
        .map(|(prev, next)| {
            (prev.firstname.clone(), next.surname.clone())
        })
        .collect::<Vec<_>>();
    
    // 打印结果
    for tuple in tuples {
        println!("{:?}", tuple);
    }
}

这种方法更灵活,如果你需要对i和i+k的元素进行配对,只需要调整skip(k)的参数即可。


两种方法都可以完美替代原有的for循环,并且支持后续链式调用collect()、fold()等迭代器方法,完全符合你的需求。

内容的提问来源于stack exchange,提问作者Ziva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:53:36