Vec::into_flattened¶
Level: reference · for working programmers
One line: Turn a Vec<[T; N]> into a Vec<T> without moving anything.
Stable since 1.80.0.
The buffer already holds the elements contiguously — a [T; N] has no indirection — so flattening is a change of type and length, not a copy. The new length is old_len * N.
Note the type: arrays, not vectors. A Vec<Vec<T>> cannot be flattened this way, because each row is a separate allocation; rows.into_iter().flatten().collect() is the version that copies.
The shape it fits is data that arrives grouped and is consumed flat — RGB pixels as [u8; 3], audio frames, fixed-width records — where you want the grouped type for the code that builds it and the flat buffer for the code that writes it out.
Going back needs chunks_exact(N) and a fallible step, because a flat length need not divide by N.
Stable since 1.80.0.
Example¶
vec_into_flattened.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
// Vec<[T; N]> becomes Vec<T>, with no copying: the buffer already holds
// the elements contiguously, so only the length changes.
let nested: Vec<[u8; 3]> = vec![[1, 2, 3], [4, 5, 6]];
let flat: Vec<u8> = nested.into_flattened();
println!("{flat:?} len {}", flat.len());
// The new length is old_len * N.
let nested: Vec<[i32; 4]> = vec![[0; 4]; 5];
println!("5 arrays of 4 -> len {}", nested.into_flattened().len());
// Note the type: it is arrays, not vectors. A Vec<Vec<T>> cannot be
// flattened this way, because its rows are separate allocations.
let rows: Vec<Vec<u8>> = vec![vec![1, 2], vec![3]];
let flat: Vec<u8> = rows.into_iter().flatten().collect();
println!("Vec<Vec<u8>> needs an iterator: {flat:?}");
// N == 0 collapses everything to nothing.
let empty: Vec<[u8; 0]> = vec![[], []];
println!("two empty arrays flatten to len {}", empty.into_flattened().len());
// Real shape: pixels or samples arriving grouped, consumed flat.
let pixels: Vec<[u8; 3]> = vec![[255, 0, 0], [0, 255, 0]];
let bytes = pixels.into_flattened();
println!("{} bytes ready to write: {bytes:?}", bytes.len());
// The reverse trip needs chunks, and it is not free of a check:
// the length must divide by N.
let back: Vec<[u8; 3]> = bytes.chunks_exact(3)
.map(|c| [c[0], c[1], c[2]])
.collect();
println!("regrouped: {back:?}");
}
Verified output of vec_into_flattened.rs — regenerated by tools/run_examples.py, never hand-typed.
[1, 2, 3, 4, 5, 6] len 6
5 arrays of 4 -> len 20
Vec<Vec<u8>> needs an iterator: [1, 2, 3]
two empty arrays flatten to len 0
6 bytes ready to write: [255, 0, 0, 0, 255, 0]
regrouped: [[255, 0, 0], [0, 255, 0]]
See also¶
Vec::into_iter— where theVec<Vec<T>>version starts- Vec of Vecs — why the nested case is different
Vec::into_boxed_slice— the other free conversion