wspeirs
December 10, 2021, 3:22am
1
I'm looking for an Iterator method that will intersperse an existing iterator, but with another iterator. For example, if I have 2 iterators that produce:
it1 => {1,2,3,4}
it2 => {6,7,8}
... then I'd like to produce: {1,6,7,8,2,6,7,8,3,6,7,8}.
In my actual code, I want to separate values in an iterator by n
0s, but I can do this easily enough with repeat_n
from Itertools. Sometime with lazy eval and no memory allocations would be great
wspeirs
December 10, 2021, 3:45am
2
I guess what I'm really asking is if there is anything out-of-the-box so I don't have to go with my poorly named iterator adaptor:
struct InterspersePaddingIterator<T, I> {
base_iter: I,
padding: T,
pad_amt: usize,
cur: usize
}
impl <T, I: Iterator<Item=T>> InterspersePaddingIterator<T, I> {
pub fn new(base_iter: I, padding: T, pad_amt: usize) -> Self {
InterspersePaddingIterator {
base_iter,
padding,
pad_amt,
cur: pad_amt
}
}
}
impl <T: Clone, I: Iterator<Item=T>> Iterator for InterspersePaddingIterator<T, I> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.cur >= self.pad_amt {
self.cur = 0;
return self.base_iter.next();
} else {
self.cur += 1;
return Some(self.padding.clone())
}
}
}
2e71828
December 10, 2021, 6:00am
3
Something like this?
fn main() {
let vals = vec![1, 2, 3, 4].into_iter();
let padding = [7, 8, 9];
let interleaved = vals.flat_map(
|x| std::iter::once(x).chain(padding.iter().copied())
);
dbg!(interleaved.collect::<Vec<_>>());
}
If you want the first and last element to both come from the value iterator, it gets a little more complicated:
fn main() {
let mut vals = vec![1, 2, 3, 4].into_iter();
let padding = vec![7, 8, 9].into_iter();
let interleaved = vals.next().into_iter().chain(
vals.flat_map(
|x| padding.clone().chain(std::iter::once(x))
)
);
dbg!(interleaved.collect::<Vec<_>>());
}
1 Like
wspeirs
December 10, 2021, 1:26pm
4
The first one is what I'm looking for... thanks @2e71828 !
system
Closed
March 10, 2022, 1:26pm
5
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.