How to initialize a vector with values 0 to n?
Asked Answered
K

2

17

How do I initialize a vector from 0 to n in Rust? Is there another way of doing that than creating an empty vector and invoking push inside a loop?

I prefer a one-liner.

Kilter answered 16/12, 2021 at 22:31 Comment(0)
R
21

A range can be collected into a vector:

pub fn sequence(n: u32) -> Vec<u32> {
    (0..n).collect()
}

Playground

Rimmer answered 16/12, 2021 at 22:34 Comment(5)
Nicer (IMO): Vec::from_iter(0..n)Sinker
Both solutions are nice and save me three lines of code :) I'll have to think a bit about which one I prefer...Saba
I think you'll see collect() used more often than from_iter() because it can just be tacked on existing iterator chains, but functionally they do the same thing.Plasticity
@Plasticity There is actually a difference: collect() needs an Iterator, while FromIterator::from_iter() takes an IntoIterator. Ranges are Iterators thus it doesn't matter, but for arrays, for example, it's [1, 2, 3].into_iter().collect::<Vec<_>>() vs. Vec::from_iter([1, 2, 3]) which is a bigger difference.Sinker
@Plasticity And since FromIterator is in the prelude since edition 2021, I'd expect much more usages of it (I use it more now, and I also saw that in other people's code). It's just shorter when you don't perform any transformation on the iterable, just converting to to another container: Container::from_iter(v) instead of v.into_iter().collect::<Container>().Sinker
M
7

Here is how you can do it as a one-liner:

let n = 4;

let v: Vec<i32> = (0..n).collect();  // the last element will be n-1
assert_eq!(v, vec![0, 1, 2, 3]);

let v: Vec<i32> = (0..=n).collect();  // the last element will be n
assert_eq!(v, vec![0, 1, 2, 3, 4]);

Or, alternatively:

let v: Vec<i32> = Vec::from_iter(0..n);  // the last element will be n-1
assert_eq!(v, vec![0, 1, 2, 3]);

let v: Vec<i32> = Vec::from_iter(0..=n);  // the last element will be n
assert_eq!(v, vec![0, 1, 2, 3, 4]);

Instead of i32 we could use other numeric types like u8, u16, i8, etc. That's because both collect() and Vec::from_iter are generic methods.

All those solutions make use of the Range or RangeInclusive structs respectively, both of which implement Iterator. That allows them to easily be converted into a Vec, which is most often done via the collect() method.

Mirabel answered 17/12, 2021 at 0:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.