Reputation: 1668
I have an IEnumerable that where T is a complex object. I need to check and see if there are 5 or more items in the list that match a lambda expression. Currently I am using something like this:
if(myList.Count(c=> c.PropertyX == desiredX && c.Y != undesiredY) >= 5)...
However, I myList grows to containing 10K+ objects this becomes a huge bottle neck and more than likely it will have found a match in the first 100 items (but I can't make that assumption).
How can I do this as efficiently as possible.
Upvotes: 3
Views: 91
Reputation: 169340
How about iterating though the list using a plain old for loop?:
int count = 0;
for (int i = 0; i < myList.Count; ++i)
{
if (myList[i].PropertyX == desiredX && myList[i].Y != undesiredY)
count++;
if (count == 5)
break;
}
This should be pretty much be as fast as it gets on a single thread. Since you can't make any assumption where in the list these items may be, the time complexity of the algorithm won't be better than be O(n) where n is the number of items in the list, i.e. in the worst case scenario you may have to iterate through the entire list. And there is no faster way of iterating through a list than using a for loop that I know of :)
Upvotes: 2
Reputation: 32296
You can use a Where
to filter, then Skip
the first 4 matches and use Any
which will stop iterating once it hits the 5th match. The case where there are less than 5 matches will still have to iterate the entire list though.
if(myList.Where(c=> c.PropertyX == desiredX && c.Y != undesiredY).Skip(4).Any())
Upvotes: 3
Reputation: 18127
You can use Skip
4 elements and check if your collections has any other elements. In this way you willl not count the whole elements in the collection.
var result = myList.Where(c=>c.PropertyX == desiredX && c.Y != undesiredY);
if(result.Skip(4).Any())
{
//has >= 5 elements.
}
Upvotes: 1