Mark Whitaker
Mark Whitaker

Reputation: 8605

Select latest, distinct item with LINQ

I have a list of objects that each look something like this:

public class Item
{
    public string Id { get; set; }
    public DateTime Timestamp { get; set; }
    public string Status { get; set; }
}

In my list, the same Id may appear repeatedly, but with different Timestamp and Status values. So an example list (in JSON notation) might look like this:

[
  {
    "Id": "123",
    "Timestamp": "2017-06-21T08:00:00.000Z",
    "Status": "Ordered"
  },
  {
    "Id": "789",
    "Timestamp": "2017-06-20T09:00:00.000Z",
    "Status": "Ordered"
  },
  {
    "Id": "123",
    "Timestamp": "2017-06-20T10:00:00.000Z",
    "Status": "Dispatched"
  },
]

Note that item "123" appears twice - ordered at 8am, dispatched at 10am.

Is there a way to use LINQ to remove the duplicates (by Id) from that list, so we're left with just the latest item (by Timestamp) for each Id? In other words, I just want a list containing the latest status for each item:

[
  {
    "Id": "789",
    "Timestamp": "2017-06-20T09:00:00.000Z",
    "Status": "Ordered"
  },
  {
    "Id": "123",
    "Timestamp": "2017-06-20T10:00:00.000Z",
    "Status": "Dispatched"
  },
]

Upvotes: 1

Views: 1378

Answers (1)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

Try GroupBy by Id and sort each group by TimeStamp:

IEnumerable<Item> source = ...

var result = source
  .GroupBy(item => item.Id)
  .Select(chunk => chunk
     .OrderByDescending(item => item.TimeStamp)
     .First())
  .ToArray(); // if you want materialization

Upvotes: 7

Related Questions