Idiomatic way of recursively looping on an array

Greetings !

I am faced with implementing some algorithm (I have no way of changing it if I want to keep its properties) that could be summarized in the following way :

let buffer : Vec<Vec<_>> = Vec::with_capacity(some_array.len()); // Just there to gather the running results
buffer.push(first_value); // We provide a starting value for the algorithm

for some_value in some_array {
   let previous_value = buffer.last().unwrap(); // We retrieve the last computed value of the algorithm (or the starting value)
   let new_value = expensive_function(some_value, many, non_relevant, other, parameters);
   buffer.push(new_value);
}
// We have `buffer` that contains all of our values

For some reason, I have an itch that tells me that there is a way to use iterators for that (without triggering my lovely friend the borrow checker), is true ? If yes, what is it ?

Thanking you for taking your time to answer,

while let Some(some_value) = buffer.pop() {
    ...
}

Doesn't pop remove the previous value from buffer ?

Do you have a runnable example in the playground showing the behaviour you want? buffer[buffer.len()] always panics, so this one doesn't seem like it'd ever do what you want...

It's also unclear to me what all the types involved are. If you really have an array, then you could try just https://doc.rust-lang.org/nightly/std/primitive.array.html#method.map...

You are 100% correct. My intention was to use last.

You can use last instead of pop to not remove it.

I'm assuming your expensive_function is using previous_value (otherwise I don't see the point).

You could do something like:

let mut itrtr = some_array.into_iter();
std::iter::successors(
    Some(first), 
    |previous_value| 
        itrtr.next().map( |some_value| 
            expensive_function(some_value,previous_value,other,parameters)
       )
).collect()

I am not really convinced that it is better than what you have however.

EDIT: Or rather

some_array.into_iter().scan(
   Some(first),
   |previous_value, some_value| {let new_state = expensive_function(some_value,previous_value,other);previous_value=new_state;Some(new_state)}
).collect()

This is exactly what I was searching for ! Thank you !

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.