How do I get the latest date from a collection of objects using LINQ?

48,137

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);
Share:
48,137

Related videos on Youtube

leora
Author by

leora

Updated on October 09, 2020

Comments

  • leora
    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
      Bob Vale almost 13 years
      What is the behaviour you want if the collection is empty or if there are no items with an ExpirationDate set?
    • Offler
      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
      Bob Vale over 10 years
      @Offler But if you look, the OP uses ExpirationDate.HasValue and ExpirationDate.Value indicating that ExpirationDate is of type DateTime? (ie Nullable<DateTime>)
  • Gleno
    Gleno almost 13 years
    Heh, it did look right to me too, but where's the MaxDate()? :)
  • Bob Vale
    Bob Vale almost 13 years
    The where condition is unecessary, also Type will be DateTime? not DateTime so this code will error.
  • J. Steen
    J. Steen almost 13 years
    The where condition was removed earlier - missed the DateTime?. =)
  • Jeff Mercado
    Jeff Mercado almost 13 years
    Not necessary since it was projected to the date first.
  • Bob Vale
    Bob Vale almost 13 years
    First() will throws an exception with an empty collection
  • Bob Vale
    Bob Vale almost 13 years
    Is the Take(1) necessary as you have FirstOrDefault()?
  • Jeff Mercado
    Jeff Mercado almost 13 years
    Ok so what? Big deal. That was not a constraint in the question and therefore not a concern for us.
  • J. Steen
    J. Steen almost 13 years
    Max() operates on IComparables. =)
  • Jeff Mercado
    Jeff Mercado almost 13 years
    @J.Steen: Which I had realized after trying to verify the solutions that used Max(). :)
  • leora
    leora almost 13 years
    @J. Steen - i want to return a DateTime (not a DateTime?)
  • J. Steen
    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
    Bob Vale almost 13 years
    Because you haven't documented your return value when there are no dates set in the collection or the original collection is empty.
  • mattmc3
    mattmc3 almost 13 years
    No. 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
    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
    leora almost 13 years
    @J. Steen- i will check for empty collection up front
  • Bob Vale
    Bob Vale almost 13 years
    @ooo - its not just empty collection, its also if none of your values have an expiration date.
  • Bob Vale
    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
    Ryan Fisch almost 13 years
    Matt 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
    Ryan Fisch almost 13 years
    Bob, 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
    mattmc3 almost 13 years
    You're right - I missed that the result wasn't a DateTime but an object with a DateTime property.
  • Jeff Mercado
    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
    Bob Vale almost 13 years
    Looks good to me, it's not me thats voted you down btw, but I've voted you up.
  • Igor Beaufils
    Igor Beaufils over 3 years
    It 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)