loopsrustvectorstructrayon

How to pass a single struct instance along with an interator to map in Rust


I would like to iterate over a Vec<T>, but also pass a struct instance to my function.

The idea is that I can make a copy of the struct instance separately within each process and modify each copied struct instance based off of initial conditions that are stored in the Vec<T>.

Once again, I have a set of initial conditions that are stored in a Vec that I would like to use iteratively using .iter() to modify a set of struct instance copies.

My naive guess is that I would have to create an additional Vec<StructType> with the same length as Vec<T> and then create many copies inside of my struct instance within that Vec<StructType>, but I wanted to know if there was a more efficient way where each process could create a copy.

Here is an outline of what I am trying to do, though I am not sure what the best way to pass the struct_instance to my function is.

// --- PreProcessing ---
let struct_instance <StructType> = read_inputs(json);

// --- Iteration ---
let initial_conditions: Vec<i32> = (1..5).collect();
let test: Vec<i32> = initial_conditions
    .iter()
    .map(calculation_function)
    .collect();

I have left off the definition of the read_inputs and calculation_function from the code snippet because I feel that the full definition might detract from the main point of the question.

I later would like to parallelize this task with rayon, which is why I have chosen to use the .iter() approach.


Solution

  • iter::repeat(SomeStruct { .. }) will give you an iterator that repeats the initial struct definition.

    initial_condition.iter().zip(iter::repeat(SomeStruct { .. }) will give you an iterator that gives you a tuple (initial_condition, some_struct) for each value contained in the initial_condition collection.

    A full example would be something like the below. I changed the type of test from i32 to SomeStruct since it seems like you're wanting to collect modified versions of the initial struct, but I might be misunderstanding your requirement.

    use std::iter;
    
    #[derive(Clone, Debug)]
    struct SomeStruct {
        value: i32,
    }
    
    fn main() {
        let structs = iter::repeat(SomeStruct { value: 0 });
    
        let initial_conditions: Vec<i32> = (1..5).collect();
        let test: Vec<SomeStruct> = initial_conditions
            .iter()
            .zip(structs)
            .map(|(initial_condition, mut somestruct)| {
                somestruct.value = *initial_condition;
                somestruct
            })
            .collect();
    
    }