Does Rust have a way to apply a function/method to each element in an array or vector?
Solution 1
Rust has Iterator::map
, so you can:
some_vec.iter().map(|x| /* do something here */)
However, Iterator
s are lazy so this won't do anything by itself. You can tack a .collect()
onto the end to make a new vector with the new elements, if that's what you want:
let some_vec = vec![1, 2, 3];
let doubled: Vec<_> = some_vec.iter().map(|x| x * 2).collect();
println!("{:?}", doubled);
The standard way to perform side effects is to use a for
loop:
let some_vec = vec![1, 2, 3];
for i in &some_vec {
println!("{}", i);
}
If the side effect should modify the values in place, you can use an iterator of mutable references:
let mut some_vec = vec![1, 2, 3];
for i in &mut some_vec {
*i *= 2;
}
println!("{:?}", some_vec); // [2, 4, 6]
If you really want the functional style, you can use the .for_each()
method:
let mut some_vec = vec![1, 2, 3];
some_vec.iter_mut().for_each(|i| *i *= 2);
println!("{:?}", some_vec); // [2, 4, 6]
Solution 2
Since Rust 1.21, the std::iter::Iterator
trait defines a for_each()
combinator which can be used to apply an operation to each element in the collection. It is eager (not lazy), so collect()
is not needed:
fn main() {
let mut vec = vec![1, 2, 3, 4, 5];
vec.iter_mut().for_each(|el| *el *= 2);
println!("{:?}", vec);
}
The above code prints [2, 4, 6, 8, 10]
to the console.
Related videos on Youtube
Comments
-
krishnab almost 2 years
Does the Rust language have a way to apply a function to each element in an array or vector?
I know in Python there is the
map()
function which performs this task. In R there is thelapply()
,tapply()
, andapply()
functions that also do this.Is there an established way to vectorize a function in Rust?
-
Adrian over 8 yearsHere you go: doc.rust-lang.org/std/iter/trait.Iterator.html#method.map You can use it like:
vec![1, 2, 3].into_iter().map(|x| x * 2).collect::<Vec<_>>()
-
-
krishnab over 8 yearsSay Steve, I am just wondering if there is a performance difference between the iterator/collect approach versus the
for
loop. I knows in python there is an important performance difference between loops, list comprehensions, and themap()
function. Are there any performance guidelines for Rust on issues like this--mostly numerical computing? -
gavin over 8 yearsfor loops are sugar for iterators in Rust: doc.rust-lang.org/stable/std/iter/index.html#rust%27s-for-loop so shouldn't be :)
-
Johan over 4 years
map
returns a Map, a.k.a. as key-value pair (iterator). What I want is only the values, but in the right order (Map::values()
gives an arbitrary order. So e.g.0..10
gives me an iterator from 0 to 10. Now I want to apply '|x| x*x` to this iterator to get an iterator with all squares, so {0, 1, 4, 9, ..., 100}. -
Dominic about 3 yearsThanks but what about calling multiple functions in the map callback?
-
gavin about 3 yearsIt's a closure, you can put whatever you want in the body. Like any closure, you'll need {}s if you have more than one expression.