迭代器适配器
> 掌握迭代器的转换和过滤方法,学会使用 map、filter、take、zip 等适配器。
迭代器方法(查询适配器)
all 和 any
rust
▶ Runfn 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!("警告:数据中包含非正数");
}
}find 和 position
rust
▶ Runfn 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);
}max 和 min
rust
▶ Runfn 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
}nth 和 last
rust
▶ Runfn 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
}产生适配器(Producing Adapters)
map
rust
▶ Runfn 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]
}filter
rust
▶ Runfn 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);
}filter_map
rust
▶ Runfn 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]
}take 和 skip
rust
▶ Runfn 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]
}enumerate
rust
▶ Runfn 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);
}zip
rust
▶ Runfn 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 个
}chain
rust
▶ Runfn 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);
}cycle 和 repeat
rust
▶ Runfn 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)