rustvectoriteration

Iterate over vec of iterators in parallel


Say I've got a Vec that looks something like [[1,2,3],[4,5,6],[7,8,9]]. How would I iterate over all the inner vecs at once? That is,

for k in some_func([[1,2,3],[4,5,6],[7,8,9]]) {
    println!("{k:?}")
}
=> [1,4,7],[2,5,8],[3,6,9]

I can manually construct the transpose, but that only works if the inner iterators are finite. How would I do this for any iterator?

Edit: more scientifically, I want a version of

fn parallel_iterate<T>(items: Vec<Vec<T>>) -> Vec<Vec<T>>
where
    T: Clone,
{
    let size = items.iter().map(|row| row.len()).min().unwrap_or(0);
    let mut result = Vec::with_capacity(size);
    for index in 0..size {
        result.push(Vec::new());
        for inner in items.iter() {
            result[index].push(inner[index].clone())
        }
    }
    return result;
}

where items is of type Vec<I> and I: IntoIterator<Item = T>


Solution

  • This satisfies the signature of the edited question:

    pub fn parallel_iterate<T>(into_iters: Vec<impl IntoIterator<Item = T>>) -> Vec<Vec<T>> {
        let mut iters: Vec<_> = into_iters
            .into_iter()
            .map(IntoIterator::into_iter)
            .collect();
        let mut result = vec![];
        'outer: loop {
            let mut inner_result = Vec::with_capacity(iters.len());
            for inner_iter in &mut iters {
                let Some(item) = inner_iter.next() else {
                    break 'outer;
                };
                inner_result.push(item);
            }
            result.push(inner_result);
        }
        result
    }
    

    Playground