Predicates and Lambdas with lists and collections.

smack

Junior Member
Joined
Feb 1, 2010
Messages
182
Reaction score
80
Environment: Visual Studios 2008 using VB

(this is also valid for c# although the syntax is slightly different)

i just learned a nifty technique that you can apply to working with collections and lists. this is kind of an extension of the linq concept, it uses predicates and lambdas to accomplish what you want. this can be used with several different methods associated with lists and collections, i specifically needed this for a remove all. i'm using a list of integers for simplicity, but this applies to properties and values for any class or object.
in c# you can use anonymous delegates in addition to lambdas (in vb you need explicit delegates). :)

Code:
[SIZE=2]Dim theList As New List(Of Integer)[/SIZE] 
[SIZE=2]theList.Add(1)[/SIZE]  
[SIZE=2]theList.Add(2)[/SIZE]  
[SIZE=2]theList.Add(3)[/SIZE]  
[SIZE=2]theList.Add(4)[/SIZE]  
[SIZE=2]theList.Add(5)[/SIZE]  
[SIZE=2]theList.Add(3)[/SIZE]  
[SIZE=2]theList.Add(3)[/SIZE]  
[SIZE=2]theList.Add(3)[/SIZE] 
[SIZE=2]Debug.WriteLine("Pre-Count: " & theList.Count.ToString())[/SIZE]  
[SIZE=2]' witchcraft![/SIZE]  
[SIZE=2]theList.RemoveAll(Function(a) a = 3)[/SIZE]  
[SIZE=2]Debug.WriteLine("Post-Count: " & theList.Count.ToString())[/SIZE]
here is a slightly different example using the properties of a user defined class:

Code:
' find the object in the collection that we need.
' ToVerify is a type specific list
Current = (From x In ToVerify _
                        Where x.ID = 5 _
                        Select x).First
' set up your predicate expression with a lambda.
ToVerify.RemoveAll(Function(A) A.ID = 5)
along with RemoveAll here is a short list of some of the other methods this works with:
TrueForAll
Find
FindLast
FindAll
etc...

some related links:
Code:
[SIZE=2]hxxp://bloggingabout.net/blogs/fadzai/archive/2009/10/11/predicates-and-lambda-functions-for-filtering-and-searching.aspx[/SIZE]
   [SIZE=2]hxxp://stackoverflow.com/questions/59166/how-do-you-declare-a-predicate-delegate-inline[/SIZE]  
[SIZE=2]hxxp://msdn.microsoft.com/en-us/library/wdka673a.aspx[/SIZE]


just thought this was cool and wanted to share it, this may be one of those things where once again i am the last one to learn about it. ;)


 
like greek statistics :D

Nice post OP. :)
 
this has become one of my new favorite tricks for working with lists or collections of any type. it's very powerful, flexible, and compact.

my only real gripe is that if it doesn't find what it is looking for it throws a Linq exception telling you there is nothing there. personally i would prefer to have it return nothing or a null value and then evaluate for that, but at least the exception is specific enough that you can trap for it and handle accordingly.

this knocks the socks off having to iterate through a list and maintain indexes.

as an aside you'll notice at the end of the linq query i am using .First to get the first instance in the result set of my match. there are several other things that you can do with this as well, some of which being:

.ToList
.All
.Any
.Count
.FirstOrDefault
.ToDictionary
.ToString

etc etc etc...

it pretty much extends to you the ability to do anything you can in sql, just in code. :)

the extension you use (.First, etc...) determines how your object variable needs to be dimensioned.

ie:

Code:
[SIZE=2]Dim theList As New List(Of Integer)[/SIZE] 
[SIZE=2]theList.Add(1)[/SIZE]  
[SIZE=2]theList.Add(2)[/SIZE]  
[SIZE=2]theList.Add(3)[/SIZE]  
[SIZE=2]theList.Add(4)[/SIZE]  
[SIZE=2]theList.Add(5)[/SIZE]  
[SIZE=2]theList.Add(3)[/SIZE]  
[SIZE=2]theList.Add(3)[/SIZE]  
[SIZE=2]theList.Add(3)[/SIZE] 

Dim current As List(Of Integer)
current = From x In [SIZE=2]theList[/SIZE]_
             Where x <> 3 _
             Select x).ToList

Debug.Writeline(current.Count.ToString())

all kinds of power wrapped up in this.
 
ok, one last thing about this and then i'm done. ;)

here is a quick example on how to do use the lambda for the .ToDictionary function. essentially you use the lambda as a directive to tell the function what to use as the key.

Code:
Dim MyDictionary As Dictionary(Of MyObjects) = MyObjectList.ToDictionary(Function(e) e.PropertyToBeTheKey)

:D
 
I LIIIIKE TIIS NIIIIICE!!!!!

MY WIIIFE LIIKES --- THIS IS MY GIRLFRIEEND

.... seriously, I have always just glanced over any talk of Lambdas, and never googled anything about them... :) thanks for the info
 
haha, anytime davinci. :)

i always love to learn new little tricks and techniques like this, and when i can like to pass them along. sometimes i find these concepts hard to learn in an abstract manner, so if i can find a good tangible way to explain it, it helps re-enforce it in my own mind.

at any rate, glad you liked the post. cheers!
 
Back
Top