Another use of Seq.fold: filtering


Last night, I had to filter a bunch of entries in a sequence down to only those items that had a particular characteristic. My thought process went like this: “I have a list of objects. When I’m done, I want a list of objects that have property X, discarding everything else. Ah-ha, I want to fold the sequence into a List.” I had some other constraints, such as the other library I was using was written in C# and used List<T> instead of F# types. I don’t know that this is the best way to do things, but I’ll show it anyhow as an illustration of nifty stuff I’ve done lately.

The code takes an array of some well-defined type and then filters on that type. In this case, the type has a formalized string * int tuple with names to make it useful from C#. You can place any well defined C# data type in place to get equivalent effects. For example, imagine sorting some Person or Order business object in your F# code looking for People named Fred or Orders over $100. In our case, we have the type MyType as a stand-in. The code filters on the quality of the object and returns only those instances with that quality.

#light

 

open System.Collections.Generic

 

type MyType(propA:string, propB:int) =

    member this.PropA = propA

    member this.PropB = propB

    override this.ToString() = System.String.Format("{0} {1}", this.PropA, this.PropB)

 

let typeSeq =

    [|  new MyType("red", 4);

         new MyType("red", 3);

         new MyType("blue", 3);

         new MyType("blue", 4);

         new MyType("blue", 5);

         |]

 

let filterVals theSeq propAValue =

     theSeq |> Seq.fold(fun (acc:List<MyType>) (a:MyType) ->

                        if (a.PropA = propAValue) then

                            acc.Add(a)

                        acc) (new List<MyType>())

 

printfn("%A") (filterVals typeSeq "red")

printfn("%A") (filterVals typeSeq "blue")

This code generates the following output in the interactive window:

seq [red 4; red 3]
seq [blue 3; blue 4; blue 5]

I like this syntax bit better than the LINQ syntax as I can achieve a typed collection in a trivial manner. I’m also enjoying the notion of moving away from explicit looping constructs and towards simple functions that just do the right thing for me.

  1. Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: