Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is an efficient way to reset all values of a Vec<T> without resizing it?

Tags:

vector

rust

I can use resize, but it seems like overkill because I do not need to resize the vector, just modify its values. Using a new variable is not an option, since this vector is actually a field in a struct.

I guess that resize is efficient, and probably the answer to my question, but its name does not carry the meaning of resetting the values without modifying the size.

In C, I would use memset (in opposition to realloc).

Illustration of my question:

let my_vec_size = 42;
let mut my_vec = Vec::new();       //  'my_vec' will always have a size of 42
my_vec.resize(my_vec_size, false); //  Set the size to 42, and all values to false

// [ ... ] piece of code where the values in 'my_vec' will be modified, checked, etc ...


// now I need to reuse my_vec.
// Possibility A -> use resize again
my_vec.resize(my_vec_size, false);

// Possibility B -> iterate on the vector to modify its values (long and laborious)
for item in my_vec.iter_mut() {
    *item = false;
}

// Possibility C ?
like image 495
m.raynal Avatar asked Dec 10 '22 03:12

m.raynal


1 Answers

The most efficient way in general is to reset the values themselves (aka B):

for item in &mut my_vec { *item = false; }

For booleans it is not immediately obvious, however for a String it is important to preserve the allocated buffer of each element:

for item in &mut my_vec { item.clear(); }

If discarding and recreating the elements of the Vec is cheap, such as the case of the boolean or if the elements will be overwritten anyway, then a combination of clear and resize is easier:

my_vec.clear();
my_vec.resize(my_vec_size, false);
like image 181
Matthieu M. Avatar answered Jun 06 '23 12:06

Matthieu M.