簡體   English   中英

如何僅映射迭代器中的 Some() 值?

[英]How to map over only the Some() values in an iterator?

以下兩項工作(在 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] 自動移除選項層。 如果您的映射已經返回一個 Option 並且您想跳過 Nones,那么 filter_map 使用起來要好得多。

doc.rust-lang.org

但它不會解開閉包中的值,因為它期望返回一個 Option。

有沒有辦法只過濾 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>>());
}

好吧,我想通了,迭代器的下一個總是返回一個選項,所以你只需要把它展平:

// 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>>());

它不是在一個單一的調用中,但它更簡潔,而且我認為是慣用的。

有沒有辦法只過濾 Some 值,並通過一次調用映射這些值?

您已經使用了filter_map()

fn main() {
    let v = vec![Some(0), Some(1), None, Some(2)];
    assert_eq!(
        vec![0, 2, 4],
        v.iter()
            .filter_map(|x| x.map(|x| x * 2))
            .collect::<Vec<u8>>()
    );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM