Motivated by the below topic I tried to write an iterator adapter that would take an "Iterator<Iterator<U>>
" and intersperse it with elements of type U
returning a flatened "Iterator<U>
". I would appreciate some feedback
This is my implementation:
struct IntersperseIter<I, U>
where
I: Iterator,
I::Item: Iterator<Item = U>,
U: Clone,
{
element: U,
iter: I,
peek: Option<I::Item>,
}
impl<I, U> Iterator for IntersperseIter<I, U>
where
I: Iterator,
I::Item: Iterator<Item = U>,
U: Clone,
{
type Item = U;
fn next(&mut self) -> Option<Self::Item> {
if self.peek.is_some() {
if let Some(el) = self.peek.as_mut().and_then(|inner| inner.next()) {
return Some(el);
}
self.peek.replace(self.iter.next()?);
if self.peek.is_some() {
return Some(self.element.clone());
} else {
return None;
}
} else {
return None;
}
}
}
trait IterExt<U>: Iterator {
fn intersperse_iter(mut self, element: U) -> IntersperseIter<Self, U>
where
Self: Sized,
Self::Item: Iterator<Item = U>,
U: Clone,
{
IntersperseIter {
element,
peek: self.next(),
iter: self,
}
}
}
impl<I, U> IterExt<U> for I
where
I: Iterator,
I::Item: Iterator<Item = U>,
U: Clone,
{
}
fn main() {
let a = vec!["hello", "world", "you", "are", "my", "favourite!"];
let b: Vec<_> = a
.into_iter()
.map(|word| word.chars())
.intersperse_iter(' ')
.collect::<Vec<_>>();
dbg!(b);
}
Errors:
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 0.45s
Running `target/debug/playground`
[src/main.rs:67] b = [
'h',
'e',
'l',
'l',
'o',
' ',
'w',
'o',
'r',
'l',
'd',
' ',
'y',
'o',
'u',
' ',
'a',
'r',
'e',
' ',
'm',
'y',
' ',
'f',
'a',
'v',
'o',
'u',
'r',
'i',
't',
'e',
'!',
]