I need to check if a sequence has any items satisfying some condition but at the same time NOT all items satisfying the same condition.
For example, for a sequence of 10 items I want to have TRUE if the sequence has at least one that satisfy the condition but not all:
I know I could to this:
mySequence.Any (item => item.SomeStatus == SomeConst) && !mySequence.All (item => item.SomeStatus == SomeConst)
But this is not optimal.
Is there a better way?
All() determines whether all elements of a sequence satisfy a condition. Any() determines whether any element of a sequence satisfies the condition.
First, Any() without parameters is quicker than Count() as it does not iterate through the whole collection. Second, Any() improves the readability of your code, indicating that the developer just wants to check if there are any items in the collection and isn't concerned with the exact number of items.
Yes, LINQ uses lazy evaluation. The database would be queried when the foreach starts to execute, but it would fetch all the data in one go (it would be much less efficient to do millions of queries for just one result at a time).
There are the following two ways to write LINQ queries using the Standard Query operators, in other words Select, From, Where, Orderby, Join, Groupby and many more. Using lambda expressions. Using SQL like query expressions.
You'll like this.
var anyButNotAll = mySequence .Select(item => item.SomeStatus == SomeConst) .Distinct() .Take(2) .Count() == 2;
The Take(2)
stops it iterating over any more elements than it has to.
If your concern is iterating through all of the elements in a large collection, you're okay - Any
and All
will short-circuit as soon as possible.
The statement
mySequence.Any (item => item.SomeStatus == SomeConst)
will return true as soon as one element that meets the condition is found, and
!mySequence.All (item => item.SomeStatus == SomeConst)
will return true as soon as one element does not.
Since both conditions are mutually exclusive, one of the statements is guaranteed to return after the first element, and the other is guaranteed to return as soon as the first element is found.
As pointed out by others, this solution requires starting to iterate through the collection twice. If obtaining the collection is expensive (such as in database access) or iterating over the collection does not produce the same result every time, this is not a suitable solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With