none
trouble doing FindIndex on Generic List<T>

    Question

  •  
    I have a genric list of type Feature

    List<Feature> featureList

    The Feature class has a property, PartNum which is an Int

    Now if I a variable of type Feature how can I get the index of this Feature in my featureList list?

    Feature someFeature;
    someFeature.PartNum = 11;

    //want to find based on PartNum property
    int index = featureList.FindIndex(someFeature);

    This surely can be done and must easy.  I just can figure out how to do it. 

    Anybody know how or have any ideas?
    • Edited by daktmacfan Wednesday, October 29, 2008 6:56 PM
    Wednesday, October 29, 2008 6:54 PM

Answers

  • You could override the Equals method, or you could pass a Predicate<T> delegate method into the FindIndex method.  Using Lambda expressions and Linq, you could do something like the following:

    List<Feature> list = new List<Feature>();  
     
    Feature feature1 = new Feature();  
    feature1.Value = "Test";  
    list.Add(feature1);  
     
    Feature feature2 = new Feature();  
    feature2.Value = "NoTest";  
    list.Add(feature2);  
     
    int index = list.FindIndex(f => f.Value == "NoTest");  
     
    Console.WriteLine(index); 

    This code would print a 1 to the console.  Basically, what the "f => f.Value == "NoTest"" line means is that you want to find the index of the item where the property "Value" is set to "NoTest".

    You can read up on Lambda expressions here.
    David Morton - http://blog.davemorton.net/
    • Marked as answer by daktmacfan Wednesday, October 29, 2008 7:24 PM
    Wednesday, October 29, 2008 7:19 PM
    Moderator

All replies

  • Your type Feature needs to override the Object.Equals method or implement the IEquatable Interface.
    • Proposed as answer by Peter Mourfield Wednesday, October 29, 2008 7:08 PM
    Wednesday, October 29, 2008 7:03 PM
  • You could override the Equals method, or you could pass a Predicate<T> delegate method into the FindIndex method.  Using Lambda expressions and Linq, you could do something like the following:

    List<Feature> list = new List<Feature>();  
     
    Feature feature1 = new Feature();  
    feature1.Value = "Test";  
    list.Add(feature1);  
     
    Feature feature2 = new Feature();  
    feature2.Value = "NoTest";  
    list.Add(feature2);  
     
    int index = list.FindIndex(f => f.Value == "NoTest");  
     
    Console.WriteLine(index); 

    This code would print a 1 to the console.  Basically, what the "f => f.Value == "NoTest"" line means is that you want to find the index of the item where the property "Value" is set to "NoTest".

    You can read up on Lambda expressions here.
    David Morton - http://blog.davemorton.net/
    • Marked as answer by daktmacfan Wednesday, October 29, 2008 7:24 PM
    Wednesday, October 29, 2008 7:19 PM
    Moderator
  • Ok, I have already done that, but forgot to mention.

    I am having trouble with the Predicate parameter the method takes, Predicate<Feature> match.

    How do I create that parameter I need to be able to execute the method?
    Wednesday, October 29, 2008 7:20 PM
  • "f => f.Value"

    What is this called inside of the FindIndex method?
    Wednesday, October 29, 2008 7:27 PM
  • Basically, this is shorthand for a method.  Where there's a method that takes a delegate, and the delegate defines one incoming parameter, you can put the name of the parameter to pass into the method on the left side of the "=>" symbol, and code representing the return parameter on the right. 

    So you have, as the signature of your method:

    List<T>.FindIndex(Predicate<T> predicate)  

    When you have a List<Feature>, this turns into:

    List<Feature>.FindIndex(Predicate<Feature> predicate).   

    Predicate<T> is a delegate that takes a parameter of type T, and returns a boolean. So when I write:

    FindIndex(f => f.Value == "NoTest"

    The compiler recognizes that I want to create, on the fly, a method that takes a parameter of type Feature, and names that parameter "f".  On the right side of the arrow, it uses that parameter variable, f, to generate the return parameter.  In this case, the return parameter is boolean, and is equal to the evaluation of "f.Value == "NoTest"".

    So FindIndex will now roll through each "Feature" object in your list, and test to see if "Value" equals "NoTest".  If it does, it returns true, and the FindIndex function will then return the index of the item that matches the value.

    To simplify, the following lambda expression is identical to the method immediately below it.

    f => f.Value == "NoTest" 
     
    bool FindNoTest(Feature f)  
    {  
        return f.Value == "NoTest";  

    Because it's a lambda expression, there's no need for a method name, and it kind of takes care of the details for you, including the type of "f" and what is returned. 

    I hope this makes sense.  Lambda expressions are not easy to describe.


    David Morton - http://blog.davemorton.net/
    Wednesday, October 29, 2008 7:41 PM
    Moderator
  • Thanks a lot David for taking the time to explain this.

    It's not totally clear to me, but I think that I get the general gist of it.
    Wednesday, November 05, 2008 2:28 PM