Thursday, June 26, 2014

Rust Note 2: Map and Filter

There are two things that any functional programmer will try to implement when they find out that their language of choice has lists and function literals: map and filter. Here is how you do that in Rust:

Like with many things in Rust, it's important to consider the types involved with writing these functions. Map will take a list of any type of data (in this case, a slice of borrowed references (&[T])) and return a shiny new list. Filter will take a list of borrowed references as well, and either return a list of references to references passing the predicate (any function returning a boolean value), or return a new list. Since map is returning a new list, we will make filter do that as well.

Without further adieu, here's the code for filter:

fn filter<T: Clone>(lst: &[T], function: |x: &T| -> bool) -> Vec<T>{
    let mut lVec = vec![];
    for x in lst.iter(){
        if (function(x)) { lVec.push(x.clone()); }
    }
    lVec
}


Note that whatever type you are filtering over must be a member of the Clone trait. It means that it can return something that's not a reference. So, this code will take any slice and a predicate, and return only the values for which the predicate is true.

Here is the map function:

fn map<T, U>(lst: &[T], function: |x: &T| -> U) -> Vec<U>{
    let mut lVec = vec![];
    for x in lst.iter(){
        lVec.push(function(x));
    }
    lVec
}







This doesn't need a member of Clone, because it returns a different type, as specified by the parameter "function". Function is a function literal (technically, a closure), meaning that you can give this any function that takes the type of the list and returns any other value.

No comments:

Post a Comment