Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ask "Is there exactly one element satisfying condition" in LINQ?

Tags:

c#

.net

linq

Quick question, what's the preferable way to programmaticaly ask "Is there exactly one element in this sequence that satisfies X condition?" using Linq?

i.e.

// Pretend that the .OneAndOnlyOne() method exists int[] sequence = new int[] { 1, 1, 2, 3, 5, 8 }; Assert.IsTrue(sequence.OneAndOnlyOne(x => x == 2); Assert.IsFalse(sequence.OneAndOnlyOne(x => x == 1); 

something like this can be done with:

sequence.SingleOrDefault(x => x == 2) != null; 

but that's a little clunky.

I suppose I could roll my own extension method, but this seems to be a common pattern in my code and I want to make sure there's a good clean way to do it. Is there a way using the built-in LINQ methods?

like image 335
Mike Avatar asked Jan 02 '10 23:01

Mike


People also ask

Why is LINQ lazy?

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).

What is any () in LINQ?

The Any operator is used to check whether any element in the sequence or collection satisfy the given condition. If one or more element satisfies the given condition, then it will return true. If any element does not satisfy the given condition, then it will return false.

What does LINQ Select Return?

By default, LINQ queries return a list of objects as an anonymous type. You can also specify that a query return a list of a specific type by using the Select clause.

When should we use LINQ?

LINQ in C# is used to work with data access from sources such as objects, data sets, SQL Server, and XML. LINQ stands for Language Integrated Query. LINQ is a data querying API with SQL like query syntaxes. LINQ provides functions to query cached data from all kinds of data sources.


2 Answers

You could do:

bool onlyOne = source.Where(/*condition*/).Take(2).Count() == 1 

Which will prevent count from enumerating a large sequence unnecessarily in the event of multiple matches.

like image 89
Lee Avatar answered Oct 06 '22 00:10

Lee


The simplest way is to just use Count. Single won't work for you, because it throws an exception if there isn't just that single element.

LBushkin suggests (in the comments) to use SequenceEqual to compare a sequence with another one. You could use that by skipping the first element with Skip(1), and comparing the resulting sequence to an empty sequence such as what you can get from Empty

like image 29
Michael Madsen Avatar answered Oct 06 '22 01:10

Michael Madsen