# Make a function that changes pairs of objects in 3d array

I have function for `mutation`, which takes 3d `Vec` of `Vec`s and "mutates" every pair in each of the sequential pairs (using `chunks(2)` for this) given some probability.
`children` is a 3d matrix of shape `(n_pop, n_teams, team_len)` of `Player` structure.
`mut_prob` is some real value from `[0, 1]` range.

``````pub struct Player {
sex: String,
age: usize,
city: String,
}

fn mutation(&self, children: &[Vec<Vec<Player>>]) -> Vec<Vec<Vec<Player>>> {
let range = Uniform::from(0. ..1.);
// let mutation_type = "replace"; // make split and combine later
for current_set_teams in children {
let range_over_indices = Uniform::from(1..team_len - 1);

current_set_teams
.chunks(2)
.zip(probs)
.map(|(pair, prob)| {
if prob > mut_prob {
pair
} else {
pair
}
})
.collect()
}
``````

So what this function is doing is calculates `probs` for each pair in the 2d matrix (so there will be `n_teams / 2` (n_teams is `usize`) elements in `probs`.
Then it tries to swap some of the elements for this pair of `Vec<Player>`. How can I do it correctly (if there is even the possibility to make it)?
Probably I could use some code like:

``````for team_set in children {
let temp_vec: Vec<Vec<Player>> = Vec::new();
for ind in (0..n_teams).step_by(2) {
let mut temp_child1 = team_set[ind].clone(); //
let mut temp_child2 = team_set[ind + 1].clone();
.sample_iter(&range_probs)
.take(n_teams / 2)
.collect();
if prob_vec[ind / 2] > mut_prob {
let indices_to_swap =
for swap in indices_to_swap {
temp_child1[swap] = temp_child2[swap];
temp_child2[swap] = team_set[ind][swap];
}
}
temp_vec.push(temp_child1);
temp_vec.push(temp_child2);
}
successors.push(temp_vec);
}
``````

But there are a lot of allocations so probably it is less sufficient.
How can I do it correctly?

So if I understand you want to convert one 3d structure into another by sometimes swapping adjacent members of the deepest nested `Vec`s? It's going to involve a lot of allocations no matter what because that's how your data structure is designed.

Here's one way.

If you want to reduce allocations and increase cache locality, you could flatten your 3d structure to a 1d `Vec`.

An alternative to both of these is to first clone the input, and then iterate over `chunks_exact_mut`, and perform a swap when you want to.

1 Like

Yes, exactly. Thanks for response.

I'm thinking though to write some custom newtype for the nested vecs for conviniency. But I think I need to allocate a lot since I use a lot of `Vec`'s.
Don't know if I could quit struct of `Vec`'s. Cause if I flatten it to 1d Vec, there is where problems with readability begin.