What is the idiomatic way to output the last N elements to a mutable Vec?

I am contributing Rust code to RosettaCode to both learn Rust and contribute to the Rust community. What is the best idiomatic way to output the last n elements in a mutable Vec ?

Here's roughly what I wrote, but I want to see if there is a better way:

 fn main() { let mut nums: Vec<u32> = Vec::new(); nums.push(1); nums.push(2); nums.push(3); nums.push(4); nums.push(5); let n = 2; for _ in 0..n { nums.pop(); } for e in nums { println!("{}", e) } } 

( link for the playground )

+8
rust
source share
3 answers

I would recommend using Vec::truncate :

 fn main() { let mut nums = vec![1, 2, 3, 4, 5]; let n = 2; let final_length = nums.len().saturating_sub(n); nums.truncate(final_length); println!("{:?}", nums); } 

In addition, I

  • used by saturating_sub to handle the case when there are no elements in the <> t23> vector
  • used by vec![] to easily build a vector of numbers
  • printed the whole vector in one go

Usually, when you are "something", you want to have these values. If you need values ​​in another vector, you can use Vec::split_off :

 let tail = nums.split_off(final_length); 

If you want to access elements but don’t want to create a whole new vector, you can use Vec::drain :

 for i in nums.drain(final_length..) { println!("{}", i) } 
+8
source share

An alternative approach would be to use Vec :: drain . This gives you an iterator so that you can actually use the deleted items.

 fn main() { let mut nums: Vec<u32> = Vec::new(); nums.push(1); nums.push(2); nums.push(3); nums.push(4); nums.push(5); let n = 2; let new_len = nums.len() - n; for removed_element in nums.drain(new_len..) { println!("removed: {}", removed_element); } for retained_element in nums { println!("retained: {}", retained_element); } } 

The drain method takes a RangeArgument in the form <start-inclusive>..<end-exclusive> . Both the beginning and the end can be omitted by default to the beginning / end of the vector. So, we really say that we start with new_len and exhaust to the end.

+3
source share

You should take a look at the Vec::truncate function from the standard library, which can do this for you.

( playground )

 fn main() { let mut nums: Vec<u32> = Vec::new(); nums.push(1); nums.push(2); nums.push(3); nums.push(4); nums.push(5); let n = 2; let new_len = nums.len() - n; nums.truncate(new_len); for e in nums { println!("{}", e) } } 
+2
source share

All Articles