I have a Vec
of integers and I want to create a new Vec
which contains those integers and squares of those integers. I could do this imperatively:
let v = vec![1, 2, 3];
let mut new_v = Vec::new(); // new instead of with_capacity for simplicity sake.
for &x in v.iter() {
new_v.push(x);
new_v.push(x * x);
}
println!("{:?}", new_v);
but I want to use iterators. I came up with this code:
let v = vec![1, 2, 3];
let new_v: Vec<_> = v.iter()
.flat_map(|&x| vec![x, x * x])
.collect();
println!("{:?}", new_v);
but it allocates an intermediate Vec
in the flat_map
function.
How to use flat_map
without allocations?
You can use an ArrayVec
for this.
let v = vec![1, 2, 3];
let new_v: Vec<_> = v.iter()
.flat_map(|&x| ArrayVec::from([x, x * x]))
.collect();
Making arrays be by-value iterators, so that you wouldn't need ArrayVec
has been discussed, see https://github.com/rust-lang/rust/issues/25725 and the linked PRs.