微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何仅映射迭代器中的Some值?

如何解决如何仅映射迭代器中的Some值?

以下两项工作(两次调用),但是它们太冗长了。


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要好用得多。

doc.rust-lang.org

但是它不会解开闭包中的值,因为它希望返回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>>()
    );
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。