How do I get the latest date from a collection of objects using LINQ?
Solution 1
DateTime? latestDate = myCollection.Max(r => r.ExpirationDate);
Intellisense should have given you the Max() method. =)
Now, if you must assign it to a DateTime, I would consider doing thus:
DateTime latestDate = myCollection.Where(r => r.ExpirationDate.HasValue)
.Max(r => r.ExpirationDate)
.Value;
This will not cover the case of an empty collection or a collection with only null ExpirationDates.
Depending on your earlier logic, checking
myCollection.Any(r => r.ExpirationDate.HasValue)
might be a good idea before trying to assign a value.
Solution 2
You are almost there. Use Max:
DateTime? biggest = myCollection.Max(r=>r.ExpirationDate);
If all expiration dates are null or the collection is empty you will get Null as a result, otherwise the greatest date.
As you have commented on J. Sheens' answer that you want an DateTime as a result you will need to do something about any empty collection or no items with a value, you could do this with
DateTime biggest=myCollection.Max(r=>r.ExpirationDate) ?? DateTime.MinValue
This will give you DateTime.MinValue
instead of nulls in my previous example (it also has the advantage over using the any
clause that it iterates the collection once). I picked MinValue
as an example. You could use your own abitary date.
Using the DateTime? is better, because it allows you to use null for what it's meant to mean - undefined as MinValue
could be a valid item in your list.
Solution 3
Just make sure there is a NullReference check before assigning .ExpriationDate
:
DateTime maxDate = myCollection.OrderByDescending(o => o.ExpirationDate).Take(1).FirstOrDefault().ExpirationDate;
Bob Vale had the right idea with
DateTime maxDate = objL.Max(o => o.ExpirationDate);
Related videos on Youtube
leora
Updated on October 09, 2020Comments
-
leora over 3 years
I have a list of objects and each object has a ExpirationDate property which is of type DateTime. I want to retrieve the latest date in the list. Is there an elegant way of doing that through LINQ?
Something like:
DateTime latestDate = myCollection.Where(r=>r.ExpirationDate.HasValue).MaxDate(r=>r.ExpirationDate.Value);
-
Bob Vale almost 13 yearsWhat is the behaviour you want if the collection is empty or if there are no items with an ExpirationDate set?
-
Offler over 10 years@BobVale if ExpirationDate is of Type DateTime every r will have an ExpirationDate. As DateTime is a struct, ExpirationDate can never be null.
-
Bob Vale over 10 years@Offler But if you look, the OP uses
ExpirationDate.HasValue
andExpirationDate.Value
indicating that ExpirationDate is of typeDateTime?
(ieNullable<DateTime>
)
-
-
Gleno almost 13 yearsHeh, it did look right to me too, but where's the MaxDate()? :)
-
Bob Vale almost 13 yearsThe where condition is unecessary, also Type will be DateTime? not DateTime so this code will error.
-
J. Steen almost 13 yearsThe where condition was removed earlier - missed the DateTime?. =)
-
Jeff Mercado almost 13 yearsNot necessary since it was projected to the date first.
-
Bob Vale almost 13 yearsFirst() will throws an exception with an empty collection
-
Bob Vale almost 13 yearsIs the Take(1) necessary as you have FirstOrDefault()?
-
Jeff Mercado almost 13 yearsOk so what? Big deal. That was not a constraint in the question and therefore not a concern for us.
-
J. Steen almost 13 yearsMax() operates on IComparables. =)
-
Jeff Mercado almost 13 years@J.Steen: Which I had realized after trying to verify the solutions that used
Max()
. :) -
leora almost 13 years@J. Steen - i want to return a DateTime (not a DateTime?)
-
J. Steen almost 13 years@ooo, Yeah, I figured. Edited. =) This won't cover the case if myCollection is empty or full of nulldates.
-
Bob Vale almost 13 yearsBecause you haven't documented your return value when there are no dates set in the collection or the original collection is empty.
-
mattmc3 almost 13 yearsNo. You can't ever get a null reference exception on a
DateTime
. DateTime is a value type, which means it resides on the stack.NullReferenceException
is for reference types (on the heap). See code:DateTime dt; Console.WriteLine(dt.ToShortDateString());
.Nullable<DateTime>
works the same way. -
Jeff Mercado almost 13 years@Bob: Again, not our concern. Those sorts of checks should be done prior to querying the collection anyway if the goal is to utilize LINQ effectively. Since he specifically asks for the
DateTime
, this is how it would have to be done. I could certainly offer suggestions to make this better but that would mean changing what he wants and how he wants it, I won't go there, I don't have the time. -
leora almost 13 years@J. Steen- i will check for empty collection up front
-
Bob Vale almost 13 years@ooo - its not just empty collection, its also if none of your values have an expiration date.
-
Bob Vale almost 13 years@mattmc3 - But the type would not be a DateTime, the type would be the surrounding class, The poster was indicating that FirstOrDefault could return null, so you would get a null reference exception when you accessed the ExpirationDate property on the end
-
Ryan Fisch almost 13 yearsMatt the null exception does throw if you try to access a property on the .First() if the collection is empty..its' not on DateTime that it is throw but on the object containing the datetime.
-
Ryan Fisch almost 13 yearsBob, no you are correct...I was rushing out door this morning and shoudl have slowed down...Take(1) is not required if you use First or FirstOrDefault()
-
mattmc3 almost 13 yearsYou're right - I missed that the result wasn't a DateTime but an object with a DateTime property.
-
Jeff Mercado almost 13 years@Bob: Ok updated, I had the time now (it was late late for me and needed some sleep). ;) Everything satisfactory?
-
Bob Vale almost 13 yearsLooks good to me, it's not me thats voted you down btw, but I've voted you up.
-
Igor Beaufils over 3 yearsIt works yes but really bad for perf, what if you have 1 million objects in your list ? You're gonna sort just to take the max ? Sorting at worst : O(n^2) Max at worst : O(n)