Search code examples
c#listlambdafind

How to find element in one of two lists


I can search a list, I was using this:

if (!mylist.Any(item => item.Thing == searchitem))
    {
        var myvar = mylist.Find(item => item.Thing == searchitem);
    }

However, there's a scenario where I can't find the item. And in that case I want to search another list. I'd like to do something like the following but get an error (var myvar triggers: implicitly typed variable must be initialized).

var myvar;
if (!mylist.Any(item => item.Thing == searchitem))
{
    myvar = mylist.Find(item => item.Thing == searchitem);
}
else
{
    myvar = mylist.Find(item => item.Thing == searchitem);
}
mystring = myvar.Thing;

I'm open to another structure of list.Find for achieving the same result but I really want to use myvar further in my code and not have two variables.


Solution

  • You scan myList twice: first in Any then in Find. You can try FirstOrDefault instead:

    // Either found item or null (assuming that item is class)
    var myvar = myList.FirstOrDefault(item => item.Thing == searchitem);
    

    If you have two lists you can check if you get default value and start scanning list2 in this case:

    var myvar = myList.FirstOrDefault(item => item.Thing == searchitem) ??
                myList2.FirstOrDefault(item => item.Thing == searchitem);
    
    if (myvar != null) {
      // if myvar has been found in either myList or myList2
      mystring = myvar.Thing;
      ...
    }
    

    Finally, in general case if you have several lists, you can organize them into a collection myLists and flatten it with a help of SelectMany:

    var myLists = new List<MyType>[] {
      myList,
      myList2,
      myList3,
      // ... etc.
    };
    
    var myvar = myLists
      .SelectMany(list => list)
      .FirstOrDefault(item => item.Thing == searchitem);
    

    Edit: If list and list2 are of different type then you should come to common base type, e.g.

    // I've used `object` as a common type; but you'd rather use
    // a more specific one 
    object myvar = 
      (myList.FirstOrDefault(item => item.Thing == searchitem) as object) ??
       myList2.FirstOrDefault(item => item.Thing == searchitem);