铁锈使用过滤器扫描

问题描述 投票:0回答:1

我正在尝试从迭代器中删除一些外部可变状态

fn main() {
    let non_increasing: Vec<i32> = vec![1, 0, 2, 6, 3, 9];
    let mut max_so_far = 0;
    for val in non_increasing
        .iter()
        .filter(|&&height| if height > max_so_far {max_so_far = height; true} else {false})
        {
            println!("{val}")
        }
}

# output
# 1
# 2
# 6
# 9

我发现我可以使用

scan
来做到这一点,但这使得应用
filter
变得非常困难。在这种情况下,我只对正数感兴趣,因此有一个 hack 可以绕过它(尽管只要您可以确定任何给定的硬编码值,例如
i32::MIN
不会出现,这个 hack 就可以工作)。

fn main() {
    let non_increasing: Vec<i32> = vec![1, 0, 2, 6, 3, 9];
    for val in non_increasing
        .iter()
        .scan(0, |max_so_far, &x|{
            if x > *max_so_far {
                *max_so_far = x;
                Some(x)
            } else {
                Some(i32::MIN)
            }
        })
        .filter(|&x| x != i32::MIN) 
        {
            println!("{val}")
        }
}

# output
# 1
# 2
# 6
# 9

但是,我想要一种不仅仅是黑客的方式来做到这一点,就像

fn main() {
    let non_increasing: Vec<i32> = vec![1, 0, 2, 6, 3, 9];
    for val in non_increasing
        .iter()
        .scan_filter(0, |max_so_far, &x|{
            if x > *max_so_far {
                *max_so_far = x;
                (true, Some(x))
            } else {
                (false, Some(x))
            }
        })
        {
            println!("{val}")
        }
}

# output
# 1
# 2
# 6
# 9

我该怎么做?

rust filter iterator
1个回答
0
投票

您可以利用

Option<T>
IntoIterator
:

fn main() {
    let non_increasing: Vec<i32> = vec![1, 0, 2, 6, 3, 9];
    for val in non_increasing
        .iter()
        .scan(0, |max_so_far, &x| {
            if x > *max_so_far {
                *max_so_far = x;
                Some(Some(x))
            } else {
                Some(None)
            }
        })
        .flatten()
    {
        println!("{val}")
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.