Skip to content

迭代器适配器

> 掌握迭代器的转换和过滤方法,学会使用 map、filter、take、zip 等适配器。

迭代器方法(查询适配器)

all 和 any

rust
fn main() {
    let numbers = vec![1, 2, 3, 4, 5];

    // all - 检查是否全部满足条件
    let all_positive = numbers.iter().all(|&x| x > 0);
    println!("全部正数:{}", all_positive);  // true

    let all_even = numbers.iter().all(|&x| x % 2 == 0);
    println!("全部偶数:{}", all_even);  // false

    // any - 检查是否有任意满足条件
    let has_even = numbers.iter().any(|&x| x % 2 == 0);
    println!("有偶数:{}", has_even);  // true

    let has_ten = numbers.iter().any(|&x| x == 10);
    println!("有 10: {}", has_ten);  // false

    // 实际应用:验证数据
    let data = vec![1, 2, 3, -4, 5];
    if !data.iter().all(|&x| x > 0) {
        println!("警告:数据中包含非正数");
    }
}
▶ Run

find 和 position

rust
fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    // find - 查找第一个满足条件的元素(返回引用)
    let found = numbers.iter().find(|&&x| x > 5);
    println!("找到第一个 >5 的数:{:?}", found);  // Some(&6)

    // find_map - 查找并转换
    let found_and_doubled = numbers.iter().find_map(|&x| {
        if x > 5 {
            Some(x * 2)
        } else {
            None
        }
    });
    println!("找到并翻倍:{:?}", found_and_doubled);  // Some(&12)

    // position - 查找索引
    let pos = numbers.iter().position(|&x| x == 5);
    println!("5 的位置:{:?}", pos);  // Some(4)

    // rposition - 从右向左查找
    let rpos = numbers.iter().rposition(|&x| x > 5);
    println!("最后一个 >5 的位置:{:?}", rpos);  // Some(9)

    // 实际应用
    let users = vec![
        ("alice", 25),
        ("bob", 30),
        ("charlie", 35),
    ];
    let bob_age = users.iter().find(|&&(name, _)| name == "bob");
    println!("Bob 的信息:{:?}", bob_age);
}
▶ Run

max 和 min

rust
fn main() {
    let numbers = vec![34, 12, 78, 56, 23, 89];

    // max - 最大值
    let max = numbers.iter().max();
    println!("最大值:{:?}", max);  // Some(89)

    // min - 最小值
    let min = numbers.iter().min();
    println!("最小值:{:?}", min);  // Some(12)

    // max_by - 自定义比较
    let words = vec!["apple", "banana", "cherry", "date"];
    let longest = words.iter().max_by(|a, b| a.len().cmp(&b.len()));
    println!("最长的单词:{:?}", longest);  // Some("banana")

    // min_by_key - 按键比较
    let shortest = words.iter().min_by_key(|w| w.len());
    println!("最短的单词:{:?}", shortest);  // Some("date")

    // 对于空迭代器返回 None
    let empty: Vec<i32> = vec![];
    println!("空的最大值:{:?}", empty.iter().max());  // None
}
▶ Run

nth 和 last

rust
fn main() {
    let numbers = vec![1, 2, 3, 4, 5];

    // nth - 获取第 n 个元素(从 0 开始)
    let first = numbers.iter().nth(0);
    println!("第一个:{:?}", first);  // Some(&1)

    let third = numbers.iter().nth(2);
    println!("第三个:{:?}", third);  // Some(&3)

    // last - 最后一个元素
    let last = numbers.iter().last();
    println!("最后一个:{:?}", last);  // Some(&5)

    // 注意:nth 和 last 会消耗前面的元素
    let mut iter = numbers.iter();
    println!("{:?}", iter.nth(2));  // Some(&3),消耗了 0, 1, 2
    println!("{:?}", iter.next());  // Some(&4),下一个是 4
}
▶ Run

产生适配器(Producing Adapters)

map

rust
fn main() {
    let numbers = vec![1, 2, 3, 4, 5];

    // map - 转换每个元素
    let doubled: Vec<i32> = numbers
        .iter()
        .map(|x| x * 2)
        .collect();
    println!("翻倍:{:?}", doubled);

    // 转换为字符串
    let strings: Vec<String> = numbers
        .iter()
        .map(|x| format!("数字 {}", x))
        .collect();
    println!("格式化:{:?}", strings);

    // 链式 map
    let result: Vec<i32> = numbers
        .iter()
        .map(|x| x * 2)
        .map(|x| x + 1)
        .collect();
    println!("链式:{:?}", result);  // [3, 5, 7, 9, 11]
}
▶ Run

filter

rust
fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    // filter - 过滤元素
    let evens: Vec<&i32> = numbers
        .iter()
        .filter(|&x| x % 2 == 0)
        .collect();
    println!("偶数:{:?}", evens);

    // filter 链式
    let result: Vec<&i32> = numbers
        .iter()
        .filter(|&x| x % 2 == 0)
        .filter(|&x| *x > 5)
        .collect();
    println!("大于 5 的偶数:{:?}", result);

    // filter 与其他组合
    let sum_even: i32 = numbers
        .iter()
        .filter(|&x| x % 2 == 0)
        .sum();
    println!("偶数和:{}", sum_even);
}
▶ Run

filter_map

rust
fn main() {
    // filter_map - 过滤并转换
    let strings = vec!["1", "two", "3", "four", "5"];

    let numbers: Vec<i32> = strings
        .iter()
        .filter_map(|s| s.parse::<i32>().ok())
        .collect();
    println!("解析结果:{:?}", numbers);  // [1, 3, 5]

    // 等价于 filter + map
    let numbers2: Vec<i32> = strings
        .iter()
        .filter_map(|s| {
            s.parse::<i32>()
                .ok()
                .map(|n| n * 2)  // 只对成功解析的翻倍
        })
        .collect();
    println!("解析并翻倍:{:?}", numbers2);  // [2, 6, 10]
}
▶ Run

take 和 skip

rust
fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    // take - 取前 n 个
    let first_three: Vec<&i32> = numbers.iter().take(3).collect();
    println!("前 3 个:{:?}", first_three);

    // skip - 跳过前 n 个
    let skip_three: Vec<&i32> = numbers.iter().skip(3).collect();
    println!("跳过前 3 个:{:?}", skip_three);

    // take_while - 取到条件不满足
    let less_than_5: Vec<&i32> = numbers
        .iter()
        .take_while(|&x| *x < 5)
        .collect();
    println!("小于 5: {:?}", less_than_5);  // [1, 2, 3, 4]

    // skip_while - 跳过直到条件不满足
    let rest: Vec<&i32> = numbers
        .iter()
        .skip_while(|&x| *x < 5)
        .collect();
    println!("跳过小于 5 后剩余:{:?}", rest);  // [5, 6, 7, 8, 9, 10]
}
▶ Run

enumerate

rust
fn main() {
    let fruits = vec!["apple", "banana", "cherry"];

    // enumerate - 添加索引
    for (index, fruit) in fruits.iter().enumerate() {
        println!("{}: {}", index, fruit);
    }

    // 带起始索引(Rust 1.62+)
    for (index, fruit) in fruits.iter().enumerate() {
        println!("{}: {}", index + 1, fruit);
    }

    // 收集为带索引的元组
    let indexed: Vec<(usize, &&str)> = fruits.iter().enumerate().collect();
    println!("{:?}", indexed);
}
▶ Run

zip

rust
fn main() {
    let a = vec![1, 2, 3, 4, 5];
    let b = vec!["a", "b", "c", "d", "e"];

    // zip - 合并两个迭代器
    let zipped: Vec<_> = a.iter().zip(b.iter()).collect();
    println!("zip 结果:{:?}", zipped);
    // [(1, "a"), (2, "b"), (3, "c"), (4, "d"), (5, "e")]

    // 使用 zip 遍历
    for (num, letter) in a.iter().zip(b.iter()) {
        println!("{}: {}", num, letter);
    }

    // zip 处理不同长度的迭代器(以短的为准)
    let short = vec![1, 2, 3];
    let long = vec!["a", "b", "c", "d", "e"];
    let zipped: Vec<_> = short.iter().zip(long.iter()).collect();
    println!("不同长度:{:?}", zipped);  // 只有 3 个
}
▶ Run

chain

rust
fn main() {
    let a = vec![1, 2, 3];
    let b = vec![4, 5, 6];

    // chain - 连接两个迭代器
    let chained: Vec<&i32> = a.iter().chain(b.iter()).collect();
    println!("连接结果:{:?}", chained);
    // [1, 2, 3, 4, 5, 6]

    // 链式操作
    let result: Vec<i32> = a.iter()
        .chain(b.iter())
        .map(|&x| x * 2)
        .collect();
    println!("连接并翻倍:{:?}", result);
}
▶ Run

cycle 和 repeat

rust
fn main() {
    // cycle - 循环迭代
    let mut cycle_iter = [1, 2, 3].iter().cycle();
    println!("{:?}", cycle_iter.next());  // Some(&1)
    println!("{:?}", cycle_iter.next());  // Some(&2)
    println!("{:?}", cycle_iter.next());  // Some(&3)
    println!("{:?}", cycle_iter.next());  // Some(&1),重新开始

    // 限制循环次数
    let limited: Vec<_> = [1, 2].iter().cycle().take(5).collect();
    println!("{:?}", limited);  // [1, 2, 1, 2, 1]

    // std::iter::repeat - 重复单个值
    use std::iter::repeat;
    let nines: Vec<_> = repeat(9).take(5).collect();
    println!("{:?}", nines);  // [9, 9, 9, 9, 9]

    // std::iter::repeat_with - 使用闭包生成
    use std::iter::repeat_with;
    let mut counter = 0;
    let generated: Vec<_> = repeat_with(|| {
        counter += 1;
        counter * 10
    }).take(5).collect();
    println!("{:?}", generated);  // [10, 20, 30, 40, 50]
}




---

## 小结

- map 转换每个元素,filter 过滤元素
- filter_map 结合过滤和转换
- take 取前 n 个,skip 跳过前 n 个
- enumerate 添加索引,zip 合并两个迭代器
- chain 连接迭代器,cycle 循环迭代

## 练习题

详见:[练习题](../../exercises/19-iterators)
▶ Run