42

I've been running into situations where I feel I'm lacking a LINQ extension method which effectivelly checks if there is no match of the specified predicate in a collection. There is Any and All, but if I for instance use the following code:

if (Objects.All(u => u.Distance <= 0))

This returns true if all the objects in the collection are 0 or less yards away.

if (Objects.Any(u => u.Distance <= 0))

This returns true if there is at least one object in the collection which is 0 or less yards away from me.

So far so good, both those methods make sense and the syntax for them makes sense too. Now, if I want to check if there is no object with 0 or less distance, I'd have to invert the predicate inside the All method to >= 0 instead of <= 0 or call !All(), which in some cases results in very poorly readable code.

Is there no method which effectively does Collection.None(u => u.Distance <= 0) to check if there is no object in the collection which is 0 or less yards away? It's syntactic sugar more than an actual problem, but I just have the feeling it's missing.

aevitas
  • 3,753
  • 2
  • 28
  • 39
  • 3
    Extension methods are you friend here. If you need Collection.None, define one... – David Arno Oct 12 '13 at 19:15
  • @DavidArno There is already a method which effectively does what the question asks (`Any`). The OP doesn't like it, not because it doesn't do what the OP's looking for, but because it doesn't look pretty. What's pretty and what isn't is largely opinion based. I didn't vote, nor am I going to, but I can see why someone else might. –  Oct 12 '13 at 19:22
  • possible duplicate of [Checking if a list is empty with LINQ](http://stackoverflow.com/questions/41319/checking-if-a-list-is-empty-with-linq) – Tim Schmelter Oct 12 '13 at 19:27
  • I'm not asking how to check if a collection is empty, I'm asking if there's a method which returns true if *none* of the values in the list match the predicate. And I'm not saying I don't like `Any`, I love `Any`. I'm asking if there's a method in existence in LINQ which I feel is missing: `None`. – aevitas Oct 12 '13 at 19:50
  • 7
    No, it isn't a duplicate as "Checking if a list is empty with LINQ" is concerned with checking if a list is empty, whereas this question is concerned with handling situations where no elements of a non-empty list match some critia. – David Arno Oct 12 '13 at 19:52
  • @aevitas how does `None(somCondition)` differ from `!Any(someCondition)` or `All(!someCondition)`? SQL doesn't have such an operator either, for the same reason. In fact, how would you define `None`? Wouldn't it be `when there isn't Any item that matches someCondition` ? – Panagiotis Kanavos Feb 20 '17 at 14:06
  • @aevitas besides, there is no logic symbol in [predicate logic](https://en.wikipedia.org/wiki/Existential_quantification) either. It's either `NOT ANY 0 ¬∃` or `ALL NOT - ∀ ... ¬P(x)` – Panagiotis Kanavos Feb 20 '17 at 14:21
  • @PanagiotisKanavos That's probably the reason the designers of LINQ didn't include a method for it, makes sense now. Thanks for the link! :) – aevitas Feb 20 '17 at 17:11
  • I also think that defining none is more readable than having "!" in front of Any(). At the same time others think otherwise. – Norbert Forgacs May 29 '23 at 06:53

3 Answers3

46

None is the same as !Any, so you could define your own extension method as follows:

public static class EnumerableExtensions
{
    public static bool None<TSource>(this IEnumerable<TSource> source,
                                     Func<TSource, bool> predicate)
    {
        return !source.Any(predicate);
    }
}
dtb
  • 213,145
  • 36
  • 401
  • 431
  • None is the same as `!All` too, that's why it's so weird that there's no `None`. I guess I'll stick to writing my own extension as you suggested and hope they'll add it at a later point. – aevitas Oct 12 '13 at 19:15
  • 12
    No `!Any`. `!All` will succeed from the moment one item doesn't pass the test. None means there is no element that passes the test. `!All` could be explained as `AnyNot`. In logic, `exist neg x` is not equal to `neg exists x` – Willem Van Onsem Oct 12 '13 at 19:16
  • 6
    @aevitas `None` is not the same as `!All`, although one could create a `NotAll` extension method. But why not `HardlyAny` or `AFew` ;) – Konrad Morawski Oct 12 '13 at 19:16
  • 1
    @aevitas: As you said, using `All` you have to invert the predicate. Sometimes you need `None`; that's where I use `!Any`. – dtb Oct 12 '13 at 19:17
  • @dtb `None` may be helpful as a shorthand but isn't needed. There is no `None` symbol in [predicate logic](https://en.wikipedia.org/wiki/Existential_quantification). It's either `NOT ANY` or `ALL NOT` – Panagiotis Kanavos Feb 20 '17 at 14:21
  • If one was going to do this then unless *really* sure it wouldn't come up, it would good to have `public static bool None(this IQueryable source, Expression> predicate) => !source.Any(predicate);`. Otherwise if called on an `IQueryable` with a lamdba it would end up calling the method you have, and forcing it to be performed as an enumerable. – Jon Hanna Feb 22 '17 at 03:37
  • This is very useful to stop ReSharper from changing all your `!Any(a => a == x)` to `All(a => a != x)`. – JDR Jun 23 '17 at 22:47
6

You can write your own Extension Method:

public static bool None(this IEnumerable<T> collection, Func<T, bool> predicate)
{
  return collection.All(p=>predicate(p)==false);
}

Or on IQueryable<T> as well

public static bool None(this IQueryable<T> collection, Expression<Func<TSource, bool>> predicate)
{
  return collection.All(p=> predicate(p)==false);
}
Alireza
  • 10,237
  • 6
  • 43
  • 59
  • 3
    using `p=>!Predicate(p)` is more succinct. – King King Oct 12 '13 at 19:19
  • 2
    @KingKing But less readable, although it is my personal idea. – Alireza Oct 12 '13 at 19:21
  • @Alireza sure, it's just your feeling, I don't feel so. – King King Oct 12 '13 at 19:22
  • 3
    @KingKing Yes.I said it is my own personal feeling nothing general. But sometimes '!' hides itself behind characters :) – Alireza Oct 12 '13 at 19:26
  • 2
    `== false` is less readable, because it's unusual. Also, you can't do `predicate(p)` in the second case, though you could return `!collection.Any(predicate)` which would also have the benefit in the first example of not creating a new delegate. – Jon Hanna Feb 22 '17 at 03:33
1

Even shorter version

static class LinqExtensions
{
    public static bool None<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => !source.Any(predicate);
}
Artur Karbone
  • 1,456
  • 13
  • 11