Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 758
krishnab Avatar asked Sep 30 '15 17:09

krishnab


People also ask

How do you apply a function to each element of an array?

To apply a function to every item in an array, use array_map() . This will return a new array. $array = array(1,2,3,4,5); //each array item is iterated over and gets stored in the function parameter.

Are there arrays in Rust?

Arrays are collections of same-type-data values stored in contiguous memory locations. In Rust, arrays are created using square brackets [] and their size needs to be known at compile time. An array whose size is not defined is called a slice.

How do vectors work in Rust?

Vector is a module in Rust that provides the container space to store values. It is a contiguous resizable array type, with heap-allocated contents. It is denoted by Vec<T>. Vectors in Rust have O(1) indexing and push and pop operations in vector also take O(1) complexity.


2 Answers

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]
like image 90
Steve Klabnik Avatar answered Oct 02 '22 11:10

Steve Klabnik


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

like image 26
U007D Avatar answered Oct 02 '22 12:10

U007D