Rust是否有一种方法可以将函数/方法应用于数组或向量中的每个元素?

58

Rust语言是否有一种方法可以将函数应用于数组或向量中的每个元素?

我知道Python中有map()函数来执行此任务。在R中,还有lapply()tapply()apply()等函数可以实现这一功能。

在Rust中,是否有一种已经建立的方法来向量化函数?


1
这是链接:https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map 你可以像这样使用它:vec![1, 2, 3].into_iter().map(|x| x * 2).collect::<Vec<_>>() - Adrian
2个回答

80

Rust拥有Iterator::map,因此您可以:

some_vec.iter().map(|x| /* do something here */)

然而,Iterator是惰性的,所以它本身什么也不会做。如果您需要的话,可以在结尾处添加.collect()来创建一个带有新元素的新向量:

let some_vec = vec![1, 2, 3];
let doubled: Vec<_> = some_vec.iter().map(|x| x * 2).collect();
println!("{:?}", doubled);

执行副作用的标准方法是使用for循环:

let some_vec = vec![1, 2, 3];
for i in &some_vec {
    println!("{}", i);
}
如果副作用应该就地修改值,则可以使用可变引用的迭代器:
let mut some_vec = vec![1, 2, 3];
for i in &mut some_vec {
    *i *= 2;
}
println!("{:?}", some_vec); // [2, 4, 6]

如果您确实想使用函数式风格,可以使用.for_each()方法:

let mut some_vec = vec![1, 2, 3];
some_vec.iter_mut().for_each(|i| *i *= 2);
println!("{:?}", some_vec); // [2, 4, 6]

嘿 Steve,我在想迭代器/收集方法和for循环之间是否存在性能差异。我知道在Python中,循环、列表推导式和map()函数之间有重要的性能差异。对于Rust,在类似数值计算这样的问题上是否有任何性能指南? - krishnab
1
for循环在Rust中是迭代器的语法糖:http://doc.rust-lang.org/stable/std/iter/index.html#rust%27s-for-loop,所以不应该有问题 :) - Steve Klabnik
1
map 返回的是一个 Map,也就是键值对(迭代器)。我只想要其中的值,并且按照正确的顺序排列(Map::values() 返回的是任意顺序)。例如 0..10 会给我一个从 0 到 10 的迭代器。现在我想将 |x| x*x 应用到这个迭代器上,得到一个包含所有平方数的迭代器,即 {0, 1, 4, 9, ..., 100}。 - Johan
谢谢,不过在 map 回调函数中调用多个函数怎么办? - Dominic
这是一个闭包,你可以在其中放置任何你想要的内容。像任何闭包一样,如果你有多个表达式,你需要使用 {}。 - Steve Klabnik

30
自Rust 1.21以来,std:: iter :: Iterator trait定义了一个 for_each() combinator,可用于将操作应用于集合中的每个元素。 它是急切的(不是惰性的),因此不需要使用 collect()
fn main() {
    let mut vec = vec![1, 2, 3, 4, 5];
    vec.iter_mut().for_each(|el| *el *= 2);
    println!("{:?}", vec);  // outputs [2, 4, 6, 8, 10]
}

Rust playground


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接