【发布时间】:2020-11-18 13:25:33
【问题描述】:
我的用例是我想扫描一个迭代器,并在原始迭代器的段上产生累积值(这是用于标记器)。换句话说,它不是输入值和输出值之间的一对一映射。请注意,filter_map() 不起作用,因为我确实需要累加器值。
我找到了.scan(),这几乎就是我想要的:
#![allow(unused)]
fn main() {
let a = [1, 2, 3];
let mut iter = a.iter().scan(1, |state, &x| {
if x == 2 {
return None;
}
// each iteration, we'll multiply the state by the element
*state = *state * x;
// then, we'll yield the negation of the state
Some(-*state)
});
println!("{:?}", &iter.next());
println!("{:?}", &iter.next());
println!("{:?}", &iter.next());
}
上述输出除外
Some(-1)
None
Some(-3)
当我想要它输出时
Some(-1)
Some(-3)
None
而且,不管你怎么想,这行不通:
Some(-*state)
}).filter(|x| x.is_some());
因为我实际上并没有迭代 Options:
error[E0599]: no method named `is_some` found for reference `&{integer}` in the current scope
--> src/main.rs:15:21
|
15 | }).filter(|x| x.is_some());
| ^^^^^^^ method not found in `&{integer}`
所以这就像是故意将迭代器方法与“缺少屈服值”的情况相屏蔽。
我有什么想法可以 a) 过滤掉那些缺失的产量,或者 b) 以完全不同的方式完成上述任务吗?
【问题讨论】:
-
在这种情况下,您可以在扫描之前放置一个过滤器
let mut iter = a.iter().filter(|&&x| x!=2 ).scan(1, |state, &x| {..}),但我认为您的实际情况更复杂? -
是的,我可能做了一个不好的例子。我想做的是标记一些代码,例如从 ['l', 'e', 't', ' ', 'f', 'o', 'o', ' ', '= '] 到 ["let", "foo", "="]。因此,输入值最终将“组合”成较少数量的输出值。这可以通过 .scan() 来完成,如果我可以在我还没有完整令牌时返回 None,然后在生成的迭代器中没有这些清单。
-
您可能想从 itertools crate 中查看
group_by,它似乎是为此类用例设计的。