Search code examples
loopsrustforeachiterator

Sequential Looping and changing list


I have a 2D list of structs that must be sequentially passed into a series of loops. Each loop will change the function in a way that affects the output from the following loop. All elements must have completed the first loop before the second loop can be started.

Currently, I have a system that looks like this:

self.list.iter().flatten().for_each(|e| { e.funcOne() });
self.list.iter().flatten().for_each(|e| { e.funcTwo() });
.....

While this does work, it is not elegant - it also requires the 2d list to be repeatedly flattened. One solution could be to store the self.list.iter().flatten() into its own variable, however, this would require the cloning of said variable each time I wanted to loop through it.

My Ideal solution would include something syntactically similar to this:

self.list.iter().flatten().for_each(|e| e.funcOne()).for_each(|e| e.funcTwo()) ....... ;

Solution

  • Performance-wise flattening is fine as @Chayim Friedman mentioned. If you take a look at the flatten() source, it is not really converting the 2D-array into 1D-array. What it does is it lazily iterates over one row via a row iterator, and when the row exhausts, it switches to iterate over the next row iterator, and so on until there's no next row.

    If you want a functional (one line) solution, consider this:

    let functions = [
        ElemType::funcOne,
        ElemType::funcTwo,
    ];
    
    functions.iter().for_each(|f| self.list.iter().flatten().for_each(f));