Me Myself & C#

Manoj Garg’s Tech Bytes – What I learned Today

Using Predicates with List.Find()

Posted by Manoj Garg on July 16, 2007

Yesterday, One of my team member had a requirement for searching a List for an object having a specific value for one of its member. After some googling I found out few links explaining use of Predicates for this kind of custom searching. It solved my purpose.. so here goes how I did it 🙂

For example, we have a class Employee with members like EmpCode, First Name , Last Name etc.

public class Employee{    
    //Private members for all the below described properties
    //Public Properties   
    public String EmpCode;    
    public String FirstName;    
    public String LastName;    
    public DateTime DateOfBirth;
    public String Department;
    public String Designation;
    //Methods

    //Constructor
    public Employee(String ecode, String fname, String lname, DateTime dob, String dept, String desg)
    {
         EmpCode = ecode;
         FirstName = fname;
         LastName = lname;
         DateOfBirth = dob;
         Department = dept;
         Designation = desg;    
    }
}
 
and we have a list of Employee objects..

public class EmployeeList : List<Employee>
{ }
 

Now suppose we have a list of employees and we want to search them on the basis of their first name. There are two ways to do it.

  1. we iterate through the complete list and compare each Employee object’s FirstName property to our required value
  2. Or, we can use predicates to search the intended objects.

Following code snippet shows how to use predicate in List.Find() method

EmployeeList elist = new EmployeeList();
elist.Add(new Employee("1","Mk","Garg",DateTime.Now,"ITG","Arch"));
elist.Add(new Employee("2","P","Jain",DateTime.Now,"SE","Engg"));
elist.Add(new Employee("3","A","Goyal",DateTime.Now,"QA","Lead"));
elist.Add(new Employee("4","Bob","Matt",DateTime.Now,"HR","Mgr"));

//Find Using Inline
Employee em = elist.Find(delegate(Employee e) { return e.FirstName == "Mk"; });

Here in the above code em will have the Employee object with FirstName = “Mk”

Output will be

Prdicate example output 

These predicates can be used as annonymous functions as we used in the above code function, or  we can define a function which accepts an Object of type, we want to search, as parameter, and it returns bool value indicating whether a record mathed the criteria specified. it is a static method.  For example, in our code suppose we want to search the employees by their designation we can do it like :

Employee edesg = elist.Find(FindByDesignation);

Here FindByDesignation is a method which looks like:

private static bool FindByDesignation(Employee e){return (e.Designation == “Lead”);}

Ha-P Coding 🙂
Advertisements

16 Responses to “Using Predicates with List.Find()”

  1. nitin said

    just a little confusion…
    Find can return me more than one Employee Type object… viz.. there can be more then one employee with first name as “MK”…

    it should logically return me a collection of employee objects, and not single Employee Object???
    Am i missing something???

  2. Manoj Garg said

    Hi Nitin,

    List.Find() Method will return the first object matching the search criteria. But List class supports another method List.FindAll(), which returns all the objects matching the search criteria. so for example, if in our case we have more then one Employee object with “FirstName” as “Mk” then FindAll will return a collection of type List<Employee>.


    Manoj 🙂

  3. Exactly what I was looking for, an elegant solution. Thanks for posting!

  4. Vivek said

    Is it possible to modify the FindByDesignation method to accept the designation on the run, instead of hardcoding – “Lead”?

    if we modify this way –
    private static bool FindByDesignation(Employee e, string searchedDesignation)
    {
    }

    then how can we call the mthod in .Find(?)?
    Thanks,

  5. Manoj Garg said

    Hi Vivek,

    I am not sure if C# supports passing a parameter to a delegate the way you have suggested.

    In my opinion there are two ways to do it.

    1. Employee em = elist.Find(delegate(Employee e) { return e.FirstName == designationString; });

    here you can set value of “designationString” to your required degignation at runtime and it will return the first record with the designation passed bu you.

    2. Another way is, you can create a class variable which is set to the search string. and then in “FindByDesignation” method you can use that class variable.

    following are the link which can give a better insight into it.

    1. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=96405
    2. http://codebetter.com/blogs/peter.van.ooijen/archive/2007/10/02/parameterized-searching-in-a-list-lt-t-gt.aspx

  6. Gayani said

    Hi,

    Thank you for posting very useful content.

    Gayani

  7. Mehdi said

    I Thank you for posting very useful content.

  8. Mehdi.Azadi said

    hi ,

    after thanks of you I have a problem with working with DataGridViewComboBoxColumn that how to indicate the selected value in it.

  9. Mathieu said

    thanks!!!

  10. Jennings said

    How do you want to be remembered?

  11. John said

    anonymous is spelled wrong fyi. Thanks for the write up very helpful

  12. Niel said

    use this:

    Employee employee = elist.Find(e => e.Firstname = “Mk”);

  13. will motil said

    nice thanks
    hope it runs fairly quick

    private static List Mapunits = new List();
    private static List Requestedareasmapunits = new List();
    public static Rectangle requestedarearect = new Rectangle(0,0,0,0);

    // i just wraped the whole call and passd the search criteria
    // to be set in the class as a method parameter to the wraped
    // call itself works nice makes it less ugly
    public static List getUnitsInMapArea(Rectangle r)
    {
    //
    requestedarearect = r;
    Requestedareasmapunits = Mapunits.FindAll(isWithinRectArea);
    return Requestedareasmapunits;
    }

    private static bool isWithinRectArea(MapUnitDataManager t)
    {
    return (
    t.units_map_pos_x >= requestedarearect.X &&
    t.units_map_pos_x = requestedarearect.Y &&
    t.units_map_pos_y < requestedarearect.Y + requestedarearect.Height
    );
    }

  14. will motil said

    oops sorry forgot to add it point was now
    the seach criteria variable can be private now
    private static Rectangle requestedarearect = new Rectangle(0,0,0,0);

  15. resume examples…

    […]Using Predicates with List.Find() « Me Myself & C#[…]…

  16. msn said

    thanks. it was very helpful

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: