Lambdas and Closures and Currying. Oh my! (Part 5)

Writing

View the whole series:

Functional Programming Series

In the last two parts of this series I went over the Map and Fold (reduce) methods and so in this part I figured that I would touch on the Filter higher order function. Don’t worry, this will be the last higher order function that we will go over before we start getting into some other functional concepts.

The filter function takes a list and a function that returns a boolean. It loops through each item in the list and applies the function to determine inclusion in the result. The result is simply a filtered version of the input list. We are going to create this function as an extension method of IEnumerable.

  public static IEnumerable<T> Filter<T>(
      this IEnumerable<T> list,
      Func<T, Boolean> func)
  {
    List<T> result = new List<T>();
 
    foreach (T item in list)
    {
      if (func(item))
      {
        result.Add(item);
      }
    }
 
    return result;
  }

As you can see, this method only has one Generic parameter because the result list is always the same type as the items in the input list. This method returns "IEnumerable<T>" which is the filtered list. The function that is being passed to it "Func<T, Boolean> func" takes an item of the types in the list and returns a boolean which determines whether or not that particular item is included in the result. We simply loop through each item, using an if statement that runs the passed function on each item.

As an example of using this, I am going to use the same example list as I have in previous parts of this series.

  //declare our integer list
  List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8 };
 
  var result = numbers.Filter(x => x % 2 == 0);

Here we have our list of integers and then we call Filter on it passing in a method that checks each integer to see if it is even. We get a list back with the values 2, 4, 6, and 8. This can be used for far more than just finding even numbers in a list though.

First we will declare a simple Person class.

  public class Person
  {
    public string FirstName { get; set; }
    public string LastName { get; set; }
  }

Then we will use the new Collection initializers to declare a short list of Person objects.

  var people = new List<Person>
  { 
    new Person { FirstName = "Bob", LastName="Parker" }, 
    new Person { FirstName = "Fred", LastName="Thompson"},
    new Person { FirstName = "Bob", LastName="Smith"}
  };

Then we decide that we want to find all of the Bobs. (Oh that made me think of Office Space). We could find all of the Bob’s like this:

  var Bobs = people.Filter(x => x.FirstName.ToUpper() == "BOB");

Now that we have gone through all of these higher order functions I will now have to break it to you that Linq provides a built in method that will do pretty much exactly what all of these function do. The method for Filter is called "Where" and it takes a Predicate as a parameter, which is just a delegate declared like this:

  public delegate bool Predicate<T>(T obj);

Essentially it is the same as the Func<T, Boolean> that we used earlier, and could have been used instead but I didn’t want to throw it in without explaining it. You would use this method like this:

  var Bobs = people
  .Where(x => x.FirstName.ToUpper() == "BOB").ToList();

This works almost exactly the same as our "Filter" method with the exception that we have to add "ToList" to the call in order to have the query executed immediately, otherwise it will be turned into an expression tree that can later be executed.

Well, that wraps up our discussion of the "Filter" higher order function. As usual, I hope that you learned something from this post. In the next post we are going to discuss a fairly simple concept that a lot of people try to make super complicated, Memoization. So, until next time, happy programming.

Loved the article? Hated it? Didn’t even read it?

We’d love to hear from you.

Reach Out

Comments (2)

Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

More Insights

View All