'Fastest way to search Nested List<> in C#

I have a List<> which contains another List<>

I need to find if a given value is present in any of the items in the innermost list. If match found, I need that specific item and return.

I am doing this as shown below:

InnerList inner = null;
foreach(TopList in topListItems)
{
    inner = asn.Owners.Find(x => x.GuestId == guestId);
    if(inner != null)
         break;
}

//item found if inner is not null
//else item absent in the inner list

Any other alternate way that may run faster than this?

EDIT: Some correction: I just need to see if inner list has an item with a specific value. If yes, then I need to return the top level item that that has the match. I guess the logic is the same.



Solution 1:[1]

If you want to keep the data structure then the only improvement I see is throwing out the delegate based search and search manually. I expect an improvement of about factor two with that.

foreach(var innerList in outerList)
{
    foreach(var item in innerList)
    {
        if(item.GuestId == guestId)
            return innerList;
    }
}
return null;

If possible you could employ dictionaries in some way. But I don't know enough about your problem to tell you if that's possible. This can give a really big speedup since a search by key in a dictionary is O(1) and not just O(n).

In some situations a for loop might give a slight speedup over the foreach loop, but I don't know if this is one of them. So you'll need to benchmark.

Solution 2:[2]

This would be how I would achieve this using Linq.

var answer = from topList in TopListItems
             from innerListItem in topList.InnerList
             where innerListItem.GuestId == guestId
             select topList;

or using Lambdas as per Claytons comment

var answer = TopListItems.FirstOrDefault(topList => 
             topList.InnerList.Any(innerList => 
             innerList.GuestId == guestId));

However refactoring to use a keyed dictionary using GuestId would be faster.

Solution 3:[3]

You can do it recursively. This code probably won't work for you, but it's gonna be something like it:

public object loopList(List<object> dList,object searchvalue)
{
    foreach(object value in dList)
    {
      if(searchvalue == value)
      {
        return value;
      }
      else
      {
         loopList((List<object>)value);
       }
    }
}

Solution 4:[4]

Is the inner list sorted? If so you could use a binary search for the inner list which would provide a potential performance improvement. Additionally if you have control over the construct of the inner list, changing it to a Dictionary keyed on GuestId would give you a more optimal check.

Solution 5:[5]

Could be this?

InnerList inner = null;
foreach (var innr in outerList.SelectMany(c =>c.Owners
                              .Where(x => x.GuestId == guestId)))
{
    inner = innr;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 GianT971
Solution 4 Clayton
Solution 5 BUFK