Functional Collection Parameters in C#
Date: 2008-12-17 22:13:28

While talking through my understanding of the Select method which can be applied to collections in C# with a colleague, it became clear that C# doesn't seem to use the same names for these type of operations as are used in the world of functional programming.

Coincidentally on the same day I came across Bill Six's post about using http://billsix.blogspot.com/2008/03/functional-collection-patterns-in-ruby.html[functional collection parameters in Ruby], so I thought I'd see what the equivalent operations are in C#.

== Map

Map evaluates a high order function on all the elements in a collection and then returns a new collection containing the results of the function evaluation.

In C# we can use the 'Select' method. For example, to capitalise all the items in a list:

[source,csharp]
----

var someValues = new List<string> {"mark", "sydney", "sunny"};
var upperCaseValues = someValues.Select(item => item.ToUpper());
----

The responsibility for iterating the collection has been taken away from me and I can just focus on what I want to do with the collection rather than worrying too much about the details. A more declarative approach.

If I want to see the results of that operation I just do the following:

[source,csharp]
----

upperCaseValues.ForEach(Console.WriteLine);
----

[source,text]
----

MARK
SYDNEY
SUNNY
----

== Filter

Filter applies a predicate against all of the elements in a collection and then returns a collection of elements which matched the predicate.

Conveniently there is actually a built in delegate called 'Predicate' which when combined with the 'FindAll' method can be used to solve this problem.

[source,csharp]
----

var someValues = new List<string> {"mark", "sydney", "sunny"};
var valuesWithSIn = someValues.FindAll(item => item.Contains("s"));
valuesWithSIn.ForEach(Console.WriteLine);
----

[source,text]
----

sydney
sunny
----

If we just want the first value in the collection that matches the predicate we would use the 'Find' method instead:

[source,csharp]
----

var someValues = new List<string> {"mark", "sydney", "sunny"};
var valueWithSIn = someValues.Find(item => item.Contains("s"));
Console.WriteLine(valueWithSIn);
----

[source,text]
----

sydney
----

== Reduce

Reduce applies a high order function against all the elements in a collection and then returns a single result.

We can use the 'Aggregate' method to achieve this:

[source,csharp]
----

var someValues = new List<string> {"mark", "sydney", "sunny"};
var valuesConcatenated = someValues.Aggregate("",(accumulator, item) => accumulator + item);
Console.WriteLine(valuesConcatenated);
----

[source,text]
----

marksydneysunny
----

The "" passed in as the first parameter to 'Aggregate' is the initial value for the accumulator.

== Combining expressions

As with Ruby we can chain these expressions together to return even greater results.

For example, to get concatenate all the items which contain an s we would do the following:

[source,csharp]
----

var someValues = new List<string> {"mark", "sydney", "sunny"};
var valuesConcatenated = someValues.FindAll(item => item.Contains("s"))
                                   .Aggregate("",(accumulator, item) => accumulator + item);
Console.WriteLine(valuesConcatenated);
----

[source,text]
----

sydneysunny
----

== Overall

I really like having this high order functions available to us - it has taken away the need to write some of the most boring code that we used to have to write and makes our code more concise and easier to read.