Search code examples
rustiteratorcycle

Cycle over arrays of different sizes using iterators in Rust


I have a vector containing two vectors of different sizes:

let vectors = vec![
    vec![0, 1],
    vec![2, 3, 4]
];

I would like to create an iterator to cycle over the elements of each vector, returning:

0: [0, 2]
1: [1, 3]
2: [0, 4]
3: [1, 2]
...

In this example there are two vectors, but I would like to generalize this for k vectors.

I have tried this:

let cycles = vectors
    .into_iter()
    .map(|x| x.into_iter().cycle());

loop {
    let output: Vec<_> = cycles
        .map(|x| x.next().unwrap())
        .collect();
}

However, it does not work, because x cannot be borrowed as mutable.

error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
  --> src/main.rs:14:22
   |
14 |             .map(|x| x.next().unwrap())
   |                   -  ^^^^^^^^ cannot borrow as mutable
   |                   |
   |                   help: consider changing this to be mutable: `mut x`

I understand the error, but I fail to think of an alternative way to build this iterator. Playground.


Solution

  • You have to collect the iterators into some datastructure like Vec.

    You can then use iter_mut to iterate over mutable references which let you advance the collected iterators.

    fn main() {
        let vectors = vec![vec![0, 1], vec![2, 3, 4]];
        let mut cycles = vectors
            .into_iter()
            .map(|x| x.into_iter().cycle())
            .collect::<Vec<_>>();
        for i in 0.. {
            let output: Vec<_> = cycles.iter_mut().map(|x| x.next().unwrap()).collect();
            println!("{i}: {output:?}");
        }
    }