我有两个Vec:
Vec
let x = vec!['1', '2', '3']; let y = vec!['a', 'b', 'c'];
现在我想用迭代器来创建一个新的vec,就像['1a', '1b', '1c', '2a', '2b', '2c', '3a', '3b', '3c'],我该怎么做?
['1a', '1b', '1c', '2a', '2b', '2c', '3a', '3b', '3c']
a8jjtwal1#
最简单的方法是使用itertools机箱中提供的***cartesian product***宏
itertools
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); }
Playground
u5rb5r592#
下面是如何使用普通的Rust迭代器来实现这一点:
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); }
从两个chars构造一个String最简单的方法是在chars上进行collect迭代:
chars
String
collect
let string: String = [item_x, item_y].iter().collect();
对于x中的每一项,我们迭代y并构造这样的字符串。
x
y
x.iter().map(|&item_x| y.iter.map(move |&item_y| ...));
我们使用模式匹配来获取map闭包中的值,而不是引用。由于这一点以及char具有Copy特性的事实,我们可以将moveitem_x转换为内部闭包,从而解决任何生存期问题。作为上面代码的结果,我们得到了一个String s上迭代器的迭代器。为了扁平化这个迭代器,我们使用flatten方法(谁会想到呢?)。然后我们把扁平化的迭代器收集到结果Vec中。Playground:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=bf2987ed96303a0db0f629884492011e
map
char
Copy
move
item_x
flatten
6psbrbz93#
如果你的目标是得到两个迭代器的笛卡尔积,那么现有的答案是有意义的,如果你已经得到了向量或切片(就像最初的问题),你可以做得更好一些:
fn main() { let x = vec!['1', '2', '3']; let y = vec!['a', 'b', 'c']; let result: Vec<String> = product(&x, &y) .map(|(a, b)| format!("{}{}", a, b)) .collect(); println!("{:?}", result) } fn product<'a: 'c, 'b: 'c, 'c, T>( a: &'a [T], b: &'b [T], ) -> impl Iterator<Item = (&'a T, &'b T)> + 'c { (0..a.len()) .flat_map(|i| (0..b.len()).map(move |j| (i, j))) .map(|(i, j)| (&a[i], &b[j])) }
Playground任何基于迭代器的解决方案都必须将迭代器的全部内容存储在某个地方,但是如果你已经在向量或数组中存储了数据,你可以使用已知的大小来只存储索引。
3条答案
按热度按时间a8jjtwal1#
最简单的方法是使用
itertools
机箱中提供的***cartesian product***宏Playground
u5rb5r592#
下面是如何使用普通的Rust迭代器来实现这一点:
解释
从两个
chars
构造一个String
最简单的方法是在chars
上进行collect
迭代:对于
x
中的每一项,我们迭代y
并构造这样的字符串。我们使用模式匹配来获取
map
闭包中的值,而不是引用。由于这一点以及char
具有Copy
特性的事实,我们可以将move
item_x
转换为内部闭包,从而解决任何生存期问题。作为上面代码的结果,我们得到了一个
String
s上迭代器的迭代器。为了扁平化这个迭代器,我们使用flatten
方法(谁会想到呢?)。然后我们把扁平化的迭代器收集到结果Vec
中。Playground:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=bf2987ed96303a0db0f629884492011e
6psbrbz93#
如果你的目标是得到两个迭代器的笛卡尔积,那么现有的答案是有意义的,如果你已经得到了向量或切片(就像最初的问题),你可以做得更好一些:
Playground
任何基于迭代器的解决方案都必须将迭代器的全部内容存储在某个地方,但是如果你已经在向量或数组中存储了数据,你可以使用已知的大小来只存储索引。