[英]How do I add the same integer to each element of a vector in Rust?
In Python, if I have a list and want to add 10 to each element I would do:在 Python 中,如果我有一个列表并想为每个元素添加 10,我会这样做:
bar = [2,4,5,6,7]
bar = [x + 10 for x in bar]
resulting in: [12,14,15,16,17]
.导致:
[12,14,15,16,17]
。 How can this be done in Rust?如何在 Rust 中做到这一点? Is the only way doing a for loop and going through each vector element?
是做一个for循环并遍历每个向量元素的唯一方法吗?
The Rust way to do this is very similar to Python: use iterators!执行此操作的 Rust 方法与 Python 非常相似:使用迭代器! The rough equivalent to Python's list comprehension is
iter::map
to get the new elements, and iter::collect
to collect into a new vector (or some other kind of collection).粗略相当于 Python 的列表理解是
iter::map
来获取新元素, iter::collect
来收集到一个新的向量(或其他类型的集合)。
So for example, if bar
is a Vec<i32>
(or any other primitive integer type) and you want to add 10 to each element, try例如,如果
bar
是Vec<i32>
(或任何其他原始 integer 类型)并且您想为每个元素添加 10,请尝试
bar = bar.into_iter().map(|x| x + 10).collect();
Alternatively, you could mutate the elements in-place with或者,您可以使用
bar.iter_mut().for_each(|x| *x += 10);
This is basically like a for loop, but a bit more succinct.这基本上就像一个 for 循环,但更简洁一些。 This is generally going to be more efficient than the first method since you don't need to allocate a new vector (a sufficiently smart compiler may be able to avoid this).
这通常比第一种方法更有效,因为您不需要分配新向量(足够智能的编译器可能能够避免这种情况)。 The only downside is that this version is less flexible.
唯一的缺点是这个版本不太灵活。 The output still needs to be a vector;
output 仍然需要是一个向量; you couldn't switch to a hash set or what have you.
你不能切换到 hash 设置或你有什么。 You also wouldn't be able to keep a copy of the old vector.
您也无法保留旧向量的副本。 See below for some examples of what's possible.
请参阅下面的一些可能的示例。
fn main() {
let mut bar = vec![2, 4, 5, 6, 7];
// Overwrite the old vector
bar = bar.into_iter().map(|x| x + 10).collect();
println!("new bar: {:?}", bar);
let bar = vec![2, 4, 5, 6, 7];
// Make a completely new vector
// Note that this works only because i32 implements the Copy trait,
// so we can make copies of the elements of bar without any problems
// In more general situations, we may need to clone each element
let foo: Vec<_> = bar.iter().map(|&x| x + 10).collect();
println!("old bar: {:?} (it's still around)", bar);
println!("new foo: {:?}", foo);
use std::collections::HashSet;
let bar = vec![2, 4, 5, 6, 7];
// transform the data and collect it into a HashSet
// instead of a vector
let bar: HashSet<_> = bar.into_iter().map(|x| x + 10).collect();
println!("new bar: {:?} (note that now bar is unordered)", bar);
let mut bar = vec![2, 4, 5, 6, 7];
// Overwrite the old vector in place
bar.iter_mut().for_each(|x| *x += 10);
println!("new bar: {:?}", bar);
}
This is basic code which illustrates how to do it the way the question assumes by default.这是基本代码,说明了如何按照问题默认的方式进行操作。 It might be useful for beginners with Rust like me:
它可能对像我这样的 Rust 的初学者有用:
fn increment_mut(p: &mut Vec<i32>, to_add: i32){
for i in 0..p.len() {
p[i] += to_add;
}
}
fn main() {
let mut p = vec![2, 4, 5, 6, 7];
increment_mut(&mut p, 10);
// Print the complete vector in Debug.
println!("{:?}", p)
}
$ cargo run
[12, 14, 15, 16, 17]
iter_mut
iter_mut
fn increment_mut2(p: &mut Vec<i32>, to_add: i32) {
for x in p.iter_mut() {
*x += to_add;
}
}
fn main() {
let mut p = vec![2, 4, 5, 6, 7];
increment_mut2(&mut p, 10);
// Print the complete vector in Debug.
println!("{:?}", p)
}
$ cargo run
[12, 14, 15, 16, 17]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.