I need to build repeating sequences of characters which have to look like
'level' 0: 'x', 'a', 'a',... 'b', 'b'...,'x', 'a', 'a',... 'b', 'b'...,
'level' 1: 'x', 'x', 'a', 'a',... 'b', 'b'...,'x', ... 'a', 'a',... 'b', 'b'..., 'x', 'x', 'a', 'a',..
It can rather simply be coded for a given level with nested iterators:
fn level_n(next: impl Iterator<Item = char> + Clone) -> impl Iterator<Item = char> + Clone {
repeat(once('x').chain(next))
.take(10 as usize)
.flat_map(|v| v)
}
And then:
level_n(level_n(level_n(level_0(2))))
.cycle()
.take(2000)
.collect::<Vec<char>>();
But I can't figure out how to chain them dynamically for arbitrary n. This should look like:
let v = (0..3)
.fold(level_0(3), |a, i| level_n(a))
.cycle()
.take(2000)
.collect::<Vec<char>>();
It doesn't work because types are different, plus cycle
requires its iterator to be Clone
so can't keep it in a builder struct.
ps - here is a lame workaround by giving up on Clone
and opting to collect/into_iter (iter.cloned
didn't work either).
You could try emulating a Box<dyn Iterator<Item = char> + Clone>
indirectly:
trait CloneCharIter: Iterator<Item = char> {
fn do_clone(&self) -> Box<dyn CloneCharIter>;
}
impl<T: Iterator<Item = char> + Clone + 'static> CloneCharIter for T {
fn do_clone(&self) -> Box<dyn CloneCharIter> {
Box::new(self.clone())
}
}
impl Clone for Box<dyn CloneCharIter> {
fn clone(&self) -> Self {
self.as_ref().do_clone()
}
}
fn level_0(p: usize) -> Box<dyn CloneCharIter> {
Box::new(
['a', 'b', 'c', 'd']
.into_iter()
.flat_map(move |c| repeat(c).take(p)),
)
}
fn level_n(next: Box<dyn CloneCharIter>) -> Box<dyn CloneCharIter> {
Box::new(
repeat(once('x').chain(next))
.take(10 as usize)
.flat_map(|v| v),
)
}
let v = (0..3)
.fold(level_0(3), |a, _| level_n(a))
.cycle()
.take(2000)
.collect::<Vec<char>>();