Tal Segal
Tal Segal

Reputation: 2835

Find the newest item in a C# generic list using Linq

I have a generic list of items. Each item contains a DateTime field. I would like to find the newest item in the list using Linq in the most elegant and efficient way.

Elegance is more important than efficiency in my case, but doing this also in an efficient way would be nice.

Thank you.

After reading the answers: Here is the code (and the answer I liked):

using System.Collections.Generic;
using System.Linq;

class Item
{
    public Item Date { get; set; }
    public string Name { get; set; }
}

static void Main(string[] args)
{
    List<Item> items = CreateItems();
    Item newest;
    if (items.Count == 0)
        newest = null;
    else
        newest = items.OrderByDescending(item => item.Date).First();
}

Upvotes: 3

Views: 4814

Answers (5)

Polity
Polity

Reputation: 15130

For elegance, i would go by sorting the set based on the datetime field and returning the first item like:

set.OrderByDescending(x => x.DateTime)
   .FirstOrDefault();

This will create an in-memory representation of the sorted collection so efficiency is not that good. The most efficient solution for an unsorted set would be to loop over all items and save the newest. You can use linq for this by performing an aggregate operation which i find syntactically a mess.

Alternatively, you can store your items in a sorted collection like the SortedSet. This has a bit more complex insertion time 0(log2) instead of O(1) for most collections but it allows you to immidiatly sort on datetime and therefore selecting the newest item in O(1) rather than O(n).

Upvotes: 8

jb.
jb.

Reputation: 10351

Most of the solutions so far have to completely sort the list first (via OrderByDescending), which is unnecessary and time consuming. What you want is Jon Skeet's MoreLinq MaxBy function. Source for MaxBy is on google code.

var newest = thelist.MaxBy(x => x.DateTimeField);

Upvotes: 7

Pravin Pawar
Pravin Pawar

Reputation: 2569

try this one

 sortlist.OrderByDescending(a => a.timeStamp).First();

Upvotes: 0

JohnB
JohnB

Reputation: 13723

Try Aggregate, i.e. something like:

list.Aggregate (
    DateTime.MinValue,
    (lastOne, current) => current.GreaterThan (lastOne) ? current : lastOne
)

i.e. if your field is DateTimeField, you should write something like

list.Aggregate (
    null,
    (lastOne, current) => 
        (lastOne == null) ||
             current.DateTimeField.GreaterThan (lastOne.DateTimeField)
        ? current
        : lastOne
)

Upvotes: 0

eyossi
eyossi

Reputation: 4340

Try that:

var newItem = myList.OrderByDescending(item => item.yourDateTimeField).First();

Upvotes: 3

Related Questions