问题描述
以下两项工作(两次调用),但是它们太冗长了。
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,v.iter()
.filter_map(|x| *x)
.map(|x| x*2)
.collect::<Vec<u8>>());
}
filter_map与我想要的内容接近:
[filter_map]自动删除选项层。如果你的 映射已经返回了Option,并且您想跳过 没有,那么filter_map要好用得多。
但是它不会解开闭包中的值,因为它希望返回Option。
是否可以仅对“某些”值进行过滤,并通过一次调用映射这些值? 如:
// Fake,does not work
fn main() {
let v = vec![Some(0),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>>());
它不是一次调用的,但是它要干净得多,而且我认为是惯用的。
,有没有办法只对“某些”值进行过滤,并通过一次调用映射这些值?
您已经使用它filter_map()
:
fn main() {
let v = vec![Some(0),Some(1),None,Some(2)];
assert_eq!(
vec![0,v.iter()
.filter_map(|x| x.map(|x| x * 2))
.collect::<Vec<u8>>()
);
}