How do I concatenate two slices in Rust?

前端 未结 3 749
不思量自难忘°
不思量自难忘° 2021-02-18 21:50

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

fn main() {
    let v = (0u64 .. 10).collect::

        
相关标签:
3条回答
  • 2021-02-18 22:27

    Just use .concat() on a slice of slices:

    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 it works with arbitrary number of slices.

    (Playground link)

    0 讨论(0)
  • 2021-02-18 22:29

    You should collect() the results of the take() and extend() them with the collect()ed results of skip():

    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 implementing IntoIterator (which Skip does, as it is an Iterator).

    Edit 2: your numbers are a bit off, though; in order to get 1, 2, 3, 8, 9, 10 you should declare v as follows:

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

    Since the Range is left-closed and right-open.

    0 讨论(0)
  • 2021-02-18 22:33

    Ok, first of all, your initial sequence definition is wrong. You say you want 1, 2, 3, 8, 9, 10 as output, so it should look like:

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

    Next, you say you want to concatenate slices, so let's actually use slices:

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

    At this point, it's really down to which approach you like the most. You can turn those slices into iterators, chain, then collect...

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

    ...or make a vec and extend it with the slices directly...

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

    ...or extend using more general iterators (which will become equivalent in the future with specialisation, but I don't believe it's as efficient just yet)...

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

    ...or you could use Vec::with_capacity and push in a loop, or do the chained iterator thing, 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);
    }
    
    0 讨论(0)
提交回复
热议问题