rust - Rust 中是否有一个特性允许在没有协程等实验性功能的情况下按组进行折叠?

标签 rust iterator delimiter yield

我想避免实验性功能,所以我在生成器之前考虑其他选项。
我有一个向量 v由 0 分隔成组。这些分隔组的总和可以通过 for 循环或迭代器累加:

fn main() {
    let v = vec![55, 23, 75, 0, 12, 34, 0, 97, 71, 23, 0];

    // for loop
    let mut acc = 0;

    for &vi in &v {
        acc += vi;

        if vi == 0 {
            println!("for yield {}", acc);
            acc = 0;
        }
    }

    // iter 'loop'
    v.iter()
        .scan(0, |acc, &vi| {
            *acc += vi;
            Some(if vi == 0 {
                let total = *acc;
                *acc = 0;
                Some(total)
            } else {
                None
            })
        })
        .filter_map(|acc| acc)
        .for_each(|acc| println!("iter yield {:?}", acc));
}
scan用作临时协程,返回 Some(value)当迭代器产生一个值和 None当迭代器仍在处理时。 None被过滤掉并打印总和。
上面的例子有点微不足道,因为两个操作产生相同的结果;但是,我的项目需要消化数据流(无法收集到向量中)并有条件地折叠它们(例如,这里的条件可能是 acc 可以被 10 整除,而不是被 0 分隔)。
折叠条件本身是流水线式的,这样每个流水线都可以提供一个迭代器(想想嵌套协程)。我想看看是否有替代 Iterator::scan -> Iterator::filter_map他们是否使用迭代器。请记住,收集整个数据流是不可能的,因为该流可能是无限的。

最佳答案

for 都没有问题循环或带有 scan() 的版本.如果我正在寻找更清晰的替代方案,我会考虑使用 group_by 来自 itertools crate .这个版本很优雅,几乎可以满足您的需求:

use itertools::Itertools;

v.iter()
    .group_by(|&&vi| vi != 0)
    .into_iter()
    .map(|(_, group)| group.sum::<u32>())
    .for_each(|s| println!("sum {}", s));
问题在于它输出数字 153、0、46、0、191 和 0。0 来自这样一个事实,即它认为元素 0 只是另一个组的键(表达式 vi != 0 的结果)碰巧是假的而不是真的。要解决此问题,您需要更改 mapfilter_map与您对 scan() 所做的类似:
v.iter()
    .group_by(|&&vi| vi != 0)
    .into_iter()
    .filter_map(|(filt, group)| if filt { Some(group.sum::<u32>()) } else { None })
    .for_each(|s| println!("sum {}", s));
不完美,但仍然比原始公式更优雅,因为它使分组明确。

关于rust - Rust 中是否有一个特性允许在没有协程等实验性功能的情况下按组进行折叠?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63910226/

相关文章:

casting - 为什么我不能将具有扩展特征的 Box 转换到具有基本特征的 Box?

rust - 在向量之间使用时,如何解释大于和小于运算符 (`<` 、 `>` )?

c - C中无法迭代链表

java - 如何解析包含与我用作分隔符相同的符号的字符串?

在 C 中复制 strtok token 的内容

macros - 在 rust macro_rules 中捕获生命周期

user-interface - Rust egui 窗口大小和暗模式

python - 当有可变空间分隔列时在 python (numpy) 中加载数据集

c++ - 使用另一个 vector 迭代一个 vector 的特定元素

java - 对象数组(T[])的默认迭代器实现?