Does Rust have a way to apply a function/method to each element in an array or vector?

37,643

Solution 1

Rust has Iterator::map, so you can:

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

However, Iterators 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.

Rust playground

Share:
37,643

Related videos on Youtube

krishnab
Author by

krishnab

Grad student at UCLA.

Updated on July 09, 2022

Comments

  • krishnab
    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 the lapply(), tapply(), and apply() functions that also do this.

    Is there an established way to vectorize a function in Rust?

  • krishnab
    krishnab over 8 years
    Say 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 the map() function. Are there any performance guidelines for Rust on issues like this--mostly numerical computing?
  • gavin
    gavin over 8 years
    for loops are sugar for iterators in Rust: doc.rust-lang.org/stable/std/iter/index.html#rust%27s-for-lo‌​op so shouldn't be :)
  • Johan
    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
    Dominic about 3 years
    Thanks but what about calling multiple functions in the map callback?
  • gavin
    gavin about 3 years
    It'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.