cliftonm / morelinq

Automatically exported from code.google.com/p/morelinq
Apache License 2.0
1 stars 0 forks source link

New methods MinOrDefault and MaxOrDefault #28

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
When you start playing with LINQ queries over sequences of elements (e.g.
getting min / max value for enumerable source) sooner or later you will
come across this one -- the InvalidOperationException (“Sequence contains
no elements”).

The problem occurs as by default queries like IEnumerable<T>.Min(…) and
IEnumerable<T>.Max(…) do not play nicely if you try to execute them on an
empty sequence and just throw the exception described above. Unfortunately
these methods do not have a corresponding counterpart like Single(…) /
SingleOrDefault(…) that is smart enough to query the sequence if it is not
empty or alternatively use the default value without raising an exception.

Basically you got two options now:

    * Either perform the check on the enumerable sequence every time you
are querying it
    * OR integrate the logic in an extension method.

The second approach is much preferable so let’s add the missing link.

http://blogs.telerik.com/manoldonev/posts/08-10-17/linq_sequence_contains_no_ele
ments_extension_methods_to_the_rescue.aspx

Original issue reported on code.google.com by anton.ge...@gmail.com on 17 Sep 2009 at 8:56

GoogleCodeExporter commented 9 years ago
Compelling feature!

Original comment by Weitzhan...@gmail.com on 23 Nov 2012 at 8:37

GoogleCodeExporter commented 9 years ago
I need this right now !

Original comment by rdingw...@gmail.com on 5 Dec 2012 at 1:04

GoogleCodeExporter commented 9 years ago
You can implement this easily with a combination of using nullables and 
Prepend/Concat a null before calling  Min/Max, like this:

var some = Enumerable.Range(10, 10);
var none = Enumerable.Range(10,  0);
Console.WriteLine(some.Cast<int?>().Prepend(null).Min()); // prints 10
Console.WriteLine(none.Cast<int?>().Prepend(null).Min()); // prints null
Console.WriteLine(some.Cast<int?>().Prepend(null).Max()); // prints18
Console.WriteLine(none.Cast<int?>().Prepend(null).Max()); // prints null

Once you have a null you can use ?? fault in a value. The implementation in the 
blog article[1] suffers from iterating the sequence twice.

[1] 
http://blogs.telerik.com/xamlteam/posts/08-10-17/linq-sequence-contains-no-eleme
nts-extension-methods-to-the-rescue.aspx

Original comment by azizatif on 22 Jun 2013 at 12:15