Linq: Not Any VS All Don'T

LINQ: Not Any vs All Don't

Implementation of All according to ILSpy (as in I actually went and looked, rather than the "well, that method works a bit like ..." I might do if we were discussing the theory rather than the impact).

public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (predicate == null)
{
throw Error.ArgumentNull("predicate");
}
foreach (TSource current in source)
{
if (!predicate(current))
{
return false;
}
}
return true;
}

Implementation of Any according to ILSpy:

public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (predicate == null)
{
throw Error.ArgumentNull("predicate");
}
foreach (TSource current in source)
{
if (predicate(current))
{
return true;
}
}
return false;
}

Of course, there could be some subtle difference in the IL produced. But no, no there isn't. The IL is pretty much the same but for the obvious inversion of returning true on predicate match versus returning false on predicate mismatch.

This is linq-for-objects only of course. It's possible that some other linq provider treats one much better than the other, but then if that was the case, it's pretty much random which one got the more optimal implementation.

It would seem that the rule comes down solely to someone feeling that if(determineSomethingTrue) is simpler and more readable than if(!determineSomethingFalse). And in fairness, I think they've a bit of a point in that I often find if(!someTest) confusing* when there's an alternative test of equal verbosity and complexity that would return true for the condition we want to act upon. Yet really, I personally find nothing to favour one over the other of the two alternatives you give, and would perhaps lean very slightly toward the former if the predicate were more complicated.

*Not confusing as in I don't understand, but confusing as in I worry that there's some subtle reason for the decision that I don't understand, and it takes a few mental skips to realise that "no, they just decided to do it that way, wait what was I looking at this bit of code for again?..."

Is there a better way of calling LINQ Any + NOT All?

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.

LINQ .Any VS .Exists - What's the difference?

See documentation

List.Exists (Object method - MSDN)

Determines whether the List(T) contains elements that match the conditions defined by the specified predicate.

This exists since .NET 2.0, so before LINQ. Meant to be used with the Predicate delegate, but lambda expressions are backward compatible. Also, just List has this (not even IList)

IEnumerable.Any (Extension method - MSDN)

Determines whether any element of a sequence satisfies a condition.

This is new in .NET 3.5 and uses Func(TSource, bool) as argument, so this was intended to be used with lambda expressions and LINQ.

In behaviour, these are identical.

Is there an opposite of LINQ's All method?

All() checks that a given Predicate returns true for all items. In terms of framework development, it wouldn't make any sense to write a seperate method that checks that a given Predicate returns false for all items, as it is so easy to "not" a predicate.
However, you can write your own extension method:

public static bool None<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
return !source.Any(predicate);
}

Why does Resharper suggest that I simplify not any equal to all not equal?

It's all too easy to miss the ! at the start of the expression in your first example. You are therefore making the expression difficult to read. In addition, the first example reads as "not any equal to", whereas the second is "all not equal to". It's no coincidence that the easier to read code can be expressed as easier to read English.

Easier to read code is likely to be less buggy, as it's easier to understand what it does before changing it. It's because the second example is clearer that ReSharper recommends changing your code.

C# Linq All & Any working differently on blank array

Seems logical to me.

  • All: Are all numbers in arr greater than zero (meaning there is no number not greater than zero) => true
  • Any: Is there any number in arr that is greater than zero => false

But more important, according to Boolean Algebra:

arr.All(n => n > 0); 

gives true, because it should be the logical opposite of

arr.Any(n => !(n > 0));

which gives false (actually this is what the above two points say).

Why LINQ method Any does not check Count?

The assumption behind your question is likely:

Count is fast, why not use it?

One plausible answer of why Any doesn't use it is that Count is not always fast. The advantage of the implementation they chose is that it will have a relatively stable and low cost (i.e. roughly O(1)). It may not be fast as Count in all instances however (as you have identified).

There is no guarantee that the class that implements IList or ICollection will have a fast Count property. ConcurrentDictionary, for example, is generally slower for Count > 0 than the existing Any implementation.

Additionally, your code that uses IList should likely use ICollection since your code doesn't need the extra features that IList provides access to.

Does Any() stop on success?

As we see from the source code, Yes:

 internal static bool Any<T>(this IEnumerable<T> source, Func<T, bool> predicate) {
foreach (T element in source) {
if (predicate(element)) {
return true; // Attention to this line
}
}
return false;
}

Any() is the most efficient way to determine whether any element of a sequence satisfies a condition with LINQ.

also:a colleague suggested something along the lines of

if(!lotsOfItems.All(x => x.ID != target.ID)) since this is supposed to
stop once the conditions returns false for the first time but i'm not
sure on that, so if anyone could shed some light on this as well it
would be appreciated :>]

All() determines whether all elements of a sequence satisfy a condition. So, the enumeration of source is stopped as soon as the result can be determined.

Additional note:

The above is true if you are using Linq to objects. If you are using Linq to Database, then it will create a query and will execute it against database.

Which method performs better: .Any() vs .Count() 0?

If you are starting with something that has a .Length or .Count (such as ICollection<T>, IList<T>, List<T>, etc) - then this will be the fastest option, since it doesn't need to go through the GetEnumerator()/MoveNext()/Dispose() sequence required by Any() to check for a non-empty IEnumerable<T> sequence.

For just IEnumerable<T>, then Any() will generally be quicker, as it only has to look at one iteration. However, note that the LINQ-to-Objects implementation of Count() does check for ICollection<T> (using .Count as an optimisation) - so if your underlying data-source is directly a list/collection, there won't be a huge difference. Don't ask me why it doesn't use the non-generic ICollection...

Of course, if you have used LINQ to filter it etc (Where etc), you will have an iterator-block based sequence, and so this ICollection<T> optimisation is useless.

In general with IEnumerable<T> : stick with Any() ;-p



Related Topics



Leave a reply



Submit