How to combine two fragments in Rust?

I want to take x the first and last elements from a vector and combine them. I have the following code:

fn main() { let v = (0u64 .. 10).collect::<Vec<_>>(); let l = v.len(); vec![v.iter().take(3), v.iter().skip(l-3)]; } 

It gives me an error

 error[E0308]: mismatched types --> <anon>:4:28 | 4 | vec![v.iter().take(3), v.iter().skip(l-3)]; | ^^^^^^^^^^^^^^^^^^ expected struct `std::iter::Take`, found struct `std::iter::Skip` <anon>:4:5: 4:48 note: in this expansion of vec! (defined in <std macros>) | = note: expected type `std::iter::Take<std::slice::Iter<'_, u64>>` = note: found type `std::iter::Skip<std::slice::Iter<'_, u64>>` 

How do I get vec 1, 2, 3, 8, 9, 10 ? I am using Rust 1.12.

+7
rust
source share
3 answers

You should collect() get take() and extend() results with collect() ed skip() results:

 let mut p1 = v.iter().take(3).collect::<Vec<_>>(); let p2 = v.iter().skip(l-3); p1.extend(p2); println!("{:?}", p1); 

Edit : as Neikos said, you don’t even need to collect the result of skip() , since extend() accepts arguments that implement the IntoIterator (which Skip does since it is an Iterator ).

Edit 2 : your numbers don't work a bit; to get 1, 2, 3, 8, 9, 10 , you must declare v as follows:

 let v = (1u64 .. 11).collect::<Vec<_>>(); 

Because Range remains closed and open to the right.

+3
source share

Well, first of all, the incorrect definition of the initial sequence. You say you want 1, 2, 3, 8, 9, 10 as output, so it should look like this:

  let v = (1u64 .. 11).collect::<Vec<_>>(); 

Then you say that you want to merge the fragments, so let them actually use slices:

  let head = &v[..3]; let tail = &v[l-3..]; 

At the moment, this is really what approach you like the most. You can turn these fragments into iterators, a chain, then compile ...

  let v2: Vec<_> = head.iter().chain(tail.iter()).collect(); 

... or make vec and expand it with slices directly ...

  let mut v3 = vec![]; v3.extend_from_slice(head); v3.extend_from_slice(tail); 

... or to expand the use of more general iterators (which will become the equivalent in the future with specialization, but I still do not consider it effective) ...

  let mut v4: Vec<u64> = vec![]; v4.extend(head); v4.extend(tail); 

... or you can use Vec::with_capacity and push in a loop, or make an iterator chain, but using extend ... but I have to stop at some point.

Full example code:

 fn main() { let v = (1u64 .. 11).collect::<Vec<_>>(); let l = v.len(); let head = &v[..3]; let tail = &v[l-3..]; println!("head: {:?}", head); println!("tail: {:?}", tail); let v2: Vec<_> = head.iter().chain(tail.iter()).collect(); println!("v2: {:?}", v2); let mut v3 = vec![]; v3.extend_from_slice(head); v3.extend_from_slice(tail); println!("v3: {:?}", v3); // Explicit type to help inference. let mut v4: Vec<u64> = vec![]; v4.extend(head); v4.extend(tail); println!("v4: {:?}", v4); } 
+10
source share

Just use .concat() on the slice slice:

 fn main() { let v = (0u64 .. 10).collect::<Vec<_>>(); let l = v.len(); let first_and_last = [&v[..3], &v[l - 3..]].concat(); println!("{:?}", first_and_last); // The output is `[0, 1, 2, 7, 8, 9]` } 

This creates a new vector and works with an arbitrary number of slices.

(link for the playground)

+6
source share

All Articles