What would be the fastest way to flatten two Vec<u8>

Hi,

I am looking fo a fact way to flatten two vectors. When I say flatten I mean the following:

Let say i have two vectors:

    let a = vec![b'a',b'b',b'c',b'\n',b'b',b'c',b'\n',b'k',b'c',b'k',b'\n',b'j',b'g',b'k',b'h',b'\n'];
    let b = vec![b'a',b'b',b'\n',b'b',b'c',b'\n',b'k',b'k',b'k',b'\n',b'j',b'g',b'h',b'\n'];

What I aim to get is one vector of the following form:

  let c = vec![b'a',b'b',b'c',b'\n' , b'a',b'b',b'\n',   b'b',b'c',b'\n',  b'b',b'c',b'\n',  b'k',b'c',b'k',b'\n',  ,b'k',b'k',b'k',b'\n',  b'j',b'g',b'k',b'h',b'\n',   b'j',b'g',b'h',b'\n'];

One solution would be :blush:

fn main(){
    let a = vec![b'a',b'b',b'c',b'\n',b'b',b'c',b'\n',b'k',b'c',b'k',b'\n',b'j',b'g',b'k',b'h',b'\n'];
    let b = vec![b'a',b'b',b'\n',b'b',b'c',b'\n',b'k',b'k',b'k',b'\n',b'j',b'g',b'h',b'\n'];
    let mut c : Vec<u8> = Vec::new();

    let mut j=0;
    let mut k=0;
    
    for _i in 0..4{
        
        while a[j] != 10 {
            c.push(a[j]);
            j=j+1;
        }
        c.push(a[j]);
        j=j+1;
        
        
        while b[k] != 10 {
            c.push(b[k]);
            k=k+1;
        }
        c.push(b[k]);
        k=k+1;

    }
    println!("{:?}", c);
}

But this has many push() operations. To me this means a lot of memory alocations. Is there any other more efficient solution ?

thnx

You can pre-allocate the vector, since you know exactly how big it'll be. Replace

let mut c = Vec::new();

with

let mut c = Vec::with_capacity(a.len() + b.len());

and then each push will just be a simple copy and increment.

2 Likes

It's always a good idea to work with iterators:

let v:Vec<_> = a.into_iter().chain(b.into_iter()).collect();

But as a whole, you might want to think about what you want to do with it and maybe you can just pass around the chained iterator, avoiding the additional allocation and move.

1 Like

The problem with chaining the iterators is that the two iterators need to be interleaved based on groupings, so you'd need an iterator of iterators.

@mrmxs Here's a playground link to a solution that provides an Iterator<Item=u8> that does the grouping & interleaving.

1 Like

Oh ok, I missed that part of the question, sorry!