[英]Implement a pairwise iterator
我无法为一个函数编写代码,该函数接受一个迭代器并返回一个迭代器,该迭代器像这样成对迭代(Option<T>, T)
a = [1,2,3]
assert pairwise(a) == `[(None, 1), (Some(1), 2), (Some(2), 3)]
fn pairwise<I, T>(&xs: &I) -> I
where
I: Iterator<Item = T>,
{
[None].iter().chain(xs.iter().map(Some)).zip(xs.iter())
}
fn main() {
let data: Vec<i32> = vec![1, 2, 3];
let newdata: Vec<Option<i32>, i32> = pairwise(&data).collect();
println!("{:?}", newdata);
}
error[E0599]: no method named `iter` found for type `I` in the current scope
--> src/main.rs:3:28
|
3 | [None].iter().chain(xs.iter().map(Some)).zip(xs.iter())
| ^^^^
|
不知道为什么xs
不可迭代。 我已经在where
子句中说明了where
不是吗?
fn pairwise<I, T>(&xs: &I) -> I
这没有意义。 请参阅返回迭代器(或任何其他特征)的正确方法是什么? 当用作 for 循环变量时,`e1` 和 `&e2` 之间有什么区别? .
I: Iterator<Item = T>,
没有理由指定Item
是T
。
[None].iter()
最好使用iter::once
。
xs.iter()
标准库中没有定义iter
方法的特征。 也许你的意思是IntoIterator
?
let data: Vec<i32> = vec![1, 2, 3]
没有理由在这里指定类型; i32
是默认的整数类型。
Vec<Option<i32>, i32> Vec<Option<i32>, i32>> // original version
这不是Vec
的有效类型,您的原始表单甚至没有平衡符号。
毕竟,您面临着艰难的选择。 您的示例代码传入了一个迭代器,该迭代器具有对切片的引用,但您已经编写了断言,以便您希望获得非引用。 您还尝试两次使用任意迭代器; 不能保证这样的事情是可行的。
我看到的最通用的形式是:
use std::iter;
fn pairwise<I>(right: I) -> impl Iterator<Item = (Option<I::Item>, I::Item)>
where
I: IntoIterator + Clone,
{
let left = iter::once(None).chain(right.clone().into_iter().map(Some));
left.zip(right)
}
fn main() {
let data = vec![1, 2, 3];
let newdata: Vec<_> = pairwise(&data).collect();
assert_eq!(newdata, [(None, &1), (Some(&1), &2), (Some(&2), &3)]);
let newdata: Vec<_> = pairwise(data.iter().copied()).collect();
assert_eq!(newdata, [(None, 1), (Some(1), 2), (Some(2), 3)]);
}
另见:
我知道 OP 要求“外部成对”( [(None, 1), (Some(1), 2), (Some(2), 3)]
),但这是我如何将其调整为“内部成对”( [(1, 2), (2, 3)]
):
fn inner_pairwise<I>(right: I) -> impl Iterator<Item = (I::Item, I::Item)> where I: IntoIterator + Clone, { let left = right.clone().into_iter().skip(1); left.zip(right) }
对于这里的“内部成对”的任何人,您正在寻找Itertools::tuple_windows
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.