Fill vector with elements with increasing values

I know that I can write a loop and do it but I wondered if there is a nicer way to do it?

You can use a Range iterator:

let v: Vec<i32> = (0..100).collect();

An alternate way to write this:

use std::iter::FromIterator;
let v = Vec::from_iter(0..100);
2 Likes

Uhh... That's nice. Thanks.

2 Likes

You can also use the Extend trait with a Range iterator if you already have a pre-allocated vec:

let mut v = Vec::with_capacity(100); // My pre-allocated vec from elsewhere
v.extend(0..100);
1 Like

Keep in mind, collect and from_iter probably already preallocates the correct amount of it can, so it would be the same performance wise as what you've shown

3 Likes

I agree, in most cases (0..100).collect() is better.
Using the Extend trait is useful in cases where you're reusing a vector. For example, in a loop where you clear the vector every iteration:

let mut v: Vec::with_capacity(100);
for i in 0..10 {
    v.extend(i..i+100);
    dbg!(&v); // do stuff with v
    v.clear();
}

I think I implied that what I said was based on whether the optimizer can see through something and was unpredictable

In fact, iirc it's very predictable, collect with allocate according to the lower bound of size_hint, so ranges have a very strict lower_bound and you'll get a single allocation always

Vec::iter also has a correct bound, and map() preserves that so that very common case is also single allocation

If it matter then use fold or look at the source of whatever iterator you're collecting to check it's size_hint