I have 2 Vecs:
let x = vec!['1', '2', '3'];
let y = vec!['a', 'b', 'c'];
Now I want to use iterator to make a new vec like this ['1a', '1b', '1c', '2a', '2b', '2c', '3a', '3b', '3c']. How can I do?
I have 2 Vecs:
let x = vec!['1', '2', '3'];
let y = vec!['a', 'b', 'c'];
Now I want to use iterator to make a new vec like this ['1a', '1b', '1c', '2a', '2b', '2c', '3a', '3b', '3c']. How can I do?
Easiest way would be to use the cartesian product macro available in the itertools crate
use itertools::iproduct; // 0.10.1
fn main() {
let x = vec!['1', '2', '3'];
let y = vec!['a', 'b', 'c'];
let product: Vec<String> = iproduct!(x, y)
.map(|(a, b)| format!("{}{}", a, b))
.collect();
println!("{:?}", product);
}
Here is how to do it with vanilla Rust iterators:
fn main() {
let x = vec!['1', '2', '3'];
let y = vec!['a', 'b', 'c'];
let product: Vec<String> = x
.iter()
.map(|&item_x| y
.iter()
.map(move |&item_y| [item_x, item_y]
.iter()
.collect()
)
)
.flatten()
.collect();
println!("{:?}", product);
}
The easiest way to construct a String from two chars is to collect iterator over the chars:
let string: String = [item_x, item_y].iter().collect();
For each item in x we iterate over y and construct such string.
x.iter().map(|&item_x| y.iter.map(move |&item_y| ...));
We use pattern matching to get value in the map closure rather then references. Because of that and the fact that the char has Copy trait, we can move item_x into inner closure, resolving any lifetime issues.
As the result of the code above we get an iterator over iterators over Strings. To flatten that iterator, we use flatten method (who would think?). Then we collect the flat iterator into the resulting Vec.
Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=bf2987ed96303a0db0f629884492011e