Once again, in this series of posts I look at the parts of the .NET Framework that may seem trivial, but can really help improve your code by making it easier to write and maintain.
Today we’re going to look at two more handy LINQ extension methods: the Any() and All() methods. These methods can help you examine an enumerable collection to determine if any, or all, of the items in the collection meet some logical condition.
Any() – Checks for at least one match
The Any() method is a LINQ extension method that operates on any IEnumerable<TSource>. Its purpose is to return true if there is at least one item (or match) in a enumerable collection.
There are two forms of Any(), one of which checks for a match given a Predicate<TSource> that returns true if at least one item matches it, and one that takes no arguments (I’m ignoring the first argument and considering only extension method calling syntax) that returns true if there is at least one item in the list:
- Any()
- Determines if the sequence contains any elements (that is, is non-empty).
- Any(Predicate<TSource>)
- Determines if any item in the sequence satisfies the condition in the passed-in predicate.
So, once again, let’s load a couple of sample List<Employee> like we did last week and examine some examples. Let’s assume Employee is defined as:
1: public sealed class Employee
2: {
3: public long Id { get; set; }
4: public string Name { get; set; }
5: public double Salary { get; set; }
6: }
And let’s assume we have a couple of instances of List<Employee> as below (yes, there are more efficient ways to do empty collections, etc., but we are assuming from a calling standpoint that we do not necessarily know what is in our list for these examples):
1: // empty
2: var noEmployeeList = new List<Employee>();
3:
4: // many items
5: var manyEmployeeList = new List<Employee>
6: {
7: new Employee { Id = 1, Name = "Jim Smith", Salary = 12345.50 },
8: new Employee { Id = 7, Name = "Jane Doe", Salary = 31234.50 },
9: new Employee { Id = 9, Name = "John Doe", Salary = 13923.99 },
10: new Employee { Id = 13, Name = "Jim Smith", Salary = 30123.49 },
11: // ... etc ...
12: };
Now, if we look at the form of Any() that takes no parameters (aside from the implicit extension method source) we see that it’s really a “not empty” check. This is a very handy check to use anytime you want to see if an IEnumerable<TSource> collection is non-empty, because it’s a constant time operation (O(1)) as opposed to Count() which is constant time on ICollection implemenations,but linear (O(n)) on most others:
1: // false because noEmployeeList is empty
2: var hasAtLeastOne = noEmployeeList.Any();
3:
4: // true because manyEmployeeList has at least one item (not empty)
5: hasAtLeastOne = manyEmployeeList.Any();
Also note that Any(), even though it’s an extension method, will not save you from checking against a null reference! All of the LINQ extension methods on IEnumerable<TSource> check for a null source enumerable collection and throw an ArgumentNullException if you attempt to call them on a null reference.
So that’s the Any() that takes no additional arguments, so what about the overload that takes a Predicate<TSource>? As mentioned, this checks to see if at least one item exists in the enumerable collection that satisfies the predicate. If so, it will return true, if no items satisfy the predicate, it returns false:
1: // true because at least one employee exists in the list who's name starts with Jim
2: var hasAnyNameStartingWithJim = manyEmployeeList.Any(e => e.Name.StartsWith("Jim"));
3:
4: // false because no employees exist with an even employee id.
5: var hasAnyEvenEmployeeId = manyEmployeeList.Any(e => (e.Id % 2) == 0);
Now, this may sound like it’s very similar to First() or Single() as discussed last week (here), but keep in mind the main difference is in the return value! Any() just verifies that an item (or match) exists, so it’s great for checking for error conditions, list consistency, etc. First() and Single(), in contrast, actually search for the item (or match) and return the item itself:
1: // only checks to see if any names are single names (no space separator), good for consistency check
2: var hasAnySingleNames = manyEmployeeList.Any(e => !e.Name.Contains(' '));
3:
4: // searches for first name having only one name (no space separator), good for search
5: // finds first or returns null (default for ref types) if not found...
6: var firstSingleName = manyEmployeeList.FirstOrDefault(e => !e.Name.Contains(' '));
Each method family has their own purposes. The main thing to remember is that Any() is useful for verifying that you do (or do not) have any items meeting a given condition or to verify that a collection is non-empty, whereas the First() and Single() families are good for searching for items matching a given condition.
The All() extension method is very useful for checking enumerable collections for consistency. Just like Any() is used to check to see if an item matching a given predicate exists, All() checks to make sure every item in the collection matches the predicate. Unlike Any(), All() does not have a form that does not take a Predicate<TSource>, because this would not have meaning for All() – after all, what would All() with no additional arguments mean?
So we have only the one form that takes the predicate (in addition to the implicit source argument for the extension method syntax, of course):
- All(Predicate<TSource>)
- Returns true if and only if there is not an item in the list that fails to match the predicate condition – note that this means that empty collections will return true!
Notice that last point! If the enumerable collection is empty, All() will return true regardless of what the predicate is! This makes logical sense because a list of zero items has no items to check, and thus there is no item in the list that fail to pass the predicate:
1: // returns true if all items in the list have at least one space in them.
2: var hasAllProperNames = manyEmployeeList.All(e => e.Name.Contains(' '));
3:
4: // note that this also returns true even though the list is empty, because there is no item that fails!
5: hasAllProperNames = noEmployeeList.All(e => e.Name.Contains(' '));
Notice that we can achieve a very similar result with All() that we did with Any()? If you think about it, verifying that all items in a collection satisfy a condition is equivalent to saying that there is not any item in the list that does not satisfy the same condition!
1: // can check using all and look for all compliance
2: var allHaveProperNames = noEmployeeList.All(e => e.Name.Contains(' '));
3:
4: // or can check using any and look for violations
5: var hasSingleName = manyEmployeeList.Any(e => !e.Name.Contains(' '));
Thus, often you can write the same check with either All() or Any() and it’s purely a matter of choice or readability. My rule of thumb for readability is that if I want to perform a “positive” check – that is, that all items should satisfy a criteria – I tend to use All(), whereas if I want to perform a “negative” check – that is, that no items should satisfy a criteria – I tend to use Any() to check for the opposite of the criteria.
Inverting the usage – a collection of predicate checks
One of the interesting ways that you can stretch the bounds of these methods is to “invert” their usage, so to speak, by having a collection of predicate checks against a single item, instead of a predicate check against a collection of items.
For instance, let’s say you’re reading input from the keyboard and it has to pass a series of checks for correctness (yes, there are other ways to do this, but this is just a simple example to illustrate the point so bear with me!):
1: private static bool IsAtLeastFiveChars(string text)
2: {
3: return text.Length >= 5;
4: }
5:
6: private static bool HasASpace(string text)
7: {
8: return text.Contains(' ');
9: }
10:
11: private static bool HasNoLeadingSpace(string text)
12: {
13: return !text.StartsWith(" ");
14: }
15:
16: private static bool HasNoTrailingSpace(string text)
17: {
18: return !text.EndsWith(" ");
19: }
Now we can takes all of these checks (and they can be as complex as you want, you can verify web service requests, or anything you like) and put them in a collection, a simple, static array is perfectly sufficient and efficient for this:
1: private static Predicate<string>[] _checks = new Predicate<string>[]
2: {
3: IsAtLeastFiveChars,
4: HasASpace,
5: HasNoLeadingSpace,
6: HasNoTrailingSpace
7: };
Now we have an array of checks to run against our data, now we can take a piece of data, and easily see if it passes all these checks:
1: public static void Main()
2: {
3: // read a line of input...
4: string result = Console.ReadLine();
5:
6: // Notice the "inversion", we're seeing if all checks return true
7: // against the one piece of data!
8: bool doesPassAllChecks = _checks.All(c => c(result));
9:
10: // ...
11: }
Once again, this was just a simple example, but it just illustrates the power you can use with these methods to go beyond the bounds of just checking enumerated collections of data.
Summary
The Any() and All() extension methods in the System.Linq namespace are great methods for checking for enumerable collection consistency or violations. Used correctly they can help improve readability and simplify code that would otherwise be coded using traditional loops.
The Any() and All() only check for existence and do not search and return the items matching, for that see the post on First() and Single() here.
Hope you enjoyed the post and I’ll see you guys on the other side of the spring holiday!
Tweet Technorati Tags: C#,.NET,Little Wonders,LINQ,All,Any