Reputation: 19143
I want to process all the items in two unequally sized vecs as if they were a single unified vec.
The approach I have taken is to create a union of the two vecs using concat
however this method clones the items so that when I process the union's items the changes are applied to the clones and not to the original items.
How can I create a union of references to the original items so that when I process the items in the union I am actually processing the items in the two vecs?
pub struct Model {
pub population: Vec<Item>,
pub archive: Vec<Item>,
}
pub struct Item {
pub fitness: f32,
}
pub fn process_union(model: &Model) {
let mut union = [&model.population[..], &model.archive[..]].concat();
union.iter_mut().for_each(|item| {
item.fitness += 1.0;
});
}
#[test]
fn test_union() {
let model = Model::default();
process_union(&model);
assert_eq!(model.population[0].fitness, 1.0);
assert_eq!(model.archive[0].fitness, 1.0);
}
Upvotes: 1
Views: 1952
Reputation: 3129
Two small changes can make your code work.
First, if you want a function to process data in place, you need to use an &mut
pointer, as compared to a normal &
. &mut
gives you the ability to modify the data you are passed.
Second, iterator chaining is probably exactly what you need! Check out this modified form of your example:
pub struct Model {
pub population: Vec<Item>,
pub archive: Vec<Item>,
}
pub struct Item {
pub fitness: f32,
}
pub fn process_union(model: &mut Model) {
model.population.iter_mut()
.chain(model.archive.iter_mut())
.for_each(|item| {
item.fitness += 1.0;
});
}
#[test]
fn test_union() {
let mut model = Model::default();
process_union(&mut model);
assert_eq!(model.population[0].fitness, 1.0);
assert_eq!(model.archive[0].fitness, 1.0);
}
Upvotes: 1