Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SingleOrDefault() when the sequence contains the default value

Tags:

c#

.net

linq

I have stumbled upon an interesting scenario, which I couldn't find a solution to. Suppose I have to find the majorant in a sequence (the number that occurs at least n / 2 + 1 times, where n is the size of the sequence). This is my implementation:

public static int FindMajorant(IList<int> numbers)
{
    return numbers
        .GroupBy(x => x)
        .Where(g => g.Count() >= numbers.Count / 2 + 1)
        .Select(g => g.Key)
        .SingleOrDefault();
}

I'm using SingleOrDefault(), which returns the element if it's found in the sequence or the default value for the type: in this case, it will return 0 as it's the default value for an int. For example, my method returns 3 for the following sequence:

List<int> sampleNumbers = new List<int>() { 2, 2, 3, 3, 2, 3, 4, 3, 3 };

which is the expected behaviour.

However, what happens if the majorant in the sequence is zero (0)? It would return 0, but that way, how could I determine whether it's the zero from SingleOrDefault() as a default value, or the majorant? Perhaps, I could use Single(), but that would throw an exception which is pretty much incorrent. I could also catch this exception, but this seems a bad practice to me. So my question is, what's the preferred way to handle this situation?

like image 354
arnaudoff Avatar asked Oct 28 '15 20:10

arnaudoff


People also ask

What is the difference between single or default and firstordefault?

It returns first specific element from a collection of elements if one or more than one match found for that element. A default value is returned, if no match is found for that element in the collection. You should take care of following points while choosing Single, SingleOrDefault, First and FirstOrDefault:

What is the use of singleordefault in JavaScript?

The SingleOrDefault operator is used to return the single element of the collection or sequence. Basically, it returns the single element which specifies the given condition. Or return the default value if the given collection or sequence does not contain any value. This method can be overloaded in two different ways:

What is the use of single or default in IEnumerable?

SingleOrDefault<TSource> (IEnumerable<TSource>) Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence.

What is the use of singleordefault operator in MySQL?

The SingleOrDefault operator is used to return the single element of the collection or sequence. Basically, it returns the single element which specifies the given condition. Or return the default value if the given collection or sequence does not contain any value.


1 Answers

Use a nullable value where null indicates that there is no majorant, rather than using "0" to mean that. And conveniently enough, the default value of int? is null, so the only change needed to your code is to get a sequence of nullable ints before calling SingleOrDefault.

public static int? FindMajorant(IList<int> numbers)
{
    return numbers
        .GroupBy(x => x)
        .Where(g => g.Count() >= numbers.Count / 2 + 1)
        .Select(g => (int?)g.Key)
        .SingleOrDefault();
}
like image 68
Servy Avatar answered Sep 22 '22 16:09

Servy