简体   繁体   中英

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();
}

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).

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);

试试看:

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

Try Aggregate, ie something like:

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

ie if your field is DateTimeField, you should write something like

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

试试这个

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM