 # How to efficiently split a Vec<u8> into Vec<Vec<u8>> and sort?

Hi,

I am looking for a fast, memory efficient, solution to split Vec based on value (33u8) into a 2D Vec<Vec> -> sort 2D Vec and flatten it back into Vec. Currently I am doing it in the following way:

``````fn main() {
let a = "this is my! vector that ! needs to be sorted!and retured as flat 1D Vec<u8>";
let mut a_vec = a.as_bytes().to_owned();

let mut sort: Vec<Vec<u8>> = vec![vec![0u8; 33]; 4]; // Numbers are being calculated in a real case
let mut j = 0;
let mut l = 0;
for i in a_vec.into_iter() {
if i == 33 {
sort[j].resize(l, 0x00);
j = j + 1;
l = 0;
continue;
}
sort[j][l] = i;
l = l + 1;
}
sort[j].resize(l, 0x00);
sort.sort();

for i in sort.iter() {
println!("{:?}", String::from_utf8(i.to_vec()).unwrap());
}

// using for loop to merge it back together
}
``````

is there a better way?

``````fn main() {
let a = "this is my! vector that ! needs to be sorted!and retured as flat 1D Vec<u8>";
let mut a_vec = a.as_bytes().to_owned();

let mut sort: Vec<_> = a_vec.split(|i| *i == 33).collect();
sort.sort();

for i in sort.iter() {
println!("{:?}", String::from_utf8(i.to_vec()).unwrap());
}

let concat: Vec<u8> = sort.join(&33);
println!("{}", String::from_utf8(concat).unwrap());
}
``````
2 Likes
``````let sort = {
let mut a_elems = a.as_bytes().iter().copied();
let mut sort = vec![];
loop {
let mut v: Vec<u8> = a_elems.by_ref().take_while(|&x| x != 33).collect();
if v.is_empty() { break; }
sort.push(v);
}
sort
};
``````

EDIT: actually I had forgotten about `.split()`, that's more idiomatic , so go for @alice's solution (except for the `to_owned()` call, which should not be necessary).

1 Like