rust - 如何仅映射迭代器中的 Some() 值?
问题描述
以下两项都有效(在 2 次调用中),但感觉过于冗长。
fn main() {
let v = vec![Some(0), Some(1), None, Some(2)];
assert_eq!(
vec![0,2,4],
v.iter()
.filter(|x| x.is_some())
.map(|x| x.unwrap() * 2)
.collect::<Vec<u8>>());
assert_eq!(
vec![0,2,4],
v.iter()
.filter_map(|x| *x)
.map(|x| x*2)
.collect::<Vec<u8>>());
}
filter_map接近我想要的:
[filter_map] 自动移除选项层。如果您的映射已经返回一个选项并且您想跳过无,那么 filter_map 使用起来要好得多。
但它不会解开闭包中的值,因为它期望返回一个选项。
有没有办法既过滤 Some 值,又通过一次调用映射这些值? 如:
// Fake, does not work
fn main() {
let v = vec![Some(0), Some(1), None, Some(2)];
assert_eq!(
vec![0,2,4],
v.iter()
.map_only_some(|x| x * 2)
.collect::<Vec<u8>>());
}
解决方案
好吧,我想通了,Iterator 的 next 总是返回一个 Option,所以你只需要展平它:
// Since v.iter().next() is Some(Some(0)), the following works
assert_eq!(
vec![0,2,4],
v.iter()
.flatten()
.map(|x| x * 2)
.collect::<Vec<u8>>());
它不是在一次调用中,但它更干净,而且我认为是惯用的。
推荐阅读
- javascript - 浏览器开发工具中显示的用户详细信息
- magento2.2 - 自定义样式未转移到 magento 2.2 中的缓存文件夹
- mysql - sql group by - 诅咒和祝福
- angularjs - {{}} 在 ng-click 和 ng-repeat 中
- android - 接收服务更新的最佳实践:回调还是广播?
- java - 如何动态更新 TextView
- pandas - 根据 Pandas 数据框中的列表比较列值
- php - 根据 $_POST 值在 csv 文件上创建标题名称
- excel - 从最大值行检索列标题
- kotlin - Ktor 快速启动 HTTP API - 错误应用程序 - 未处理:GET - /snippets