Home > Enterprise >  C# How to get the lastest version of an item from each group?
C# How to get the lastest version of an item from each group?

Time:01-19

I have a collection of items and then group them up by itemID version. For an itemID with the same version value, using the example of four instances with version A

  1. If three of the “A”s have an empty “Status” while one is populated, take the one with the “Status”
  2. If all four “A”s have a “Status”, take the one with the latest modified date (do not worry about the value of “Status”)
  3. If two or three “A”s have a value in “Status” and the others are empty, take the populated one with the latest date modified
  4. If all four “A”s have an empty “Status”, take the one with the latest modified date

CodePudding user response:

You can use Linq statements. Use Min if you want the earliest date. I didn't know what you mean by the status is "Empty" so the code below is assuming that status is a string and "Empty" in this case means that the string IsNullOrWhiteSpace.

var itemsWithStatus = items.Where(item => string.IsNullOrWhiteSpace(item.Status));
if (itemsWithStatus.Any())
{
    return itemsWithStatus.Max(item => item.Date);
}
    return items.Max(item => item.Date);

CodePudding user response:

The cases are all notionally the same if you rank "has a status" as eg 1 and "doesn't have a status" as 2 and then order by this preferentially over the date

As such it seems we could have:

items.GroupBy(
  i => (i.Id, i.Version), 
  (k, g) => g.OrderBy(i => i.Status.HasValue ? 1 : 2).ThenByDescending(i => i.DateModified).First()
);

This groups items on a tuple of id and version, then uses the overload of group by that processes it's own groupings after it's made them. The items in the group are sorted first by whether status has a value (and any status of any value takes priority over any non status item) then the modified date is used to split any ties

This form of GroupBy is essentially

items.GroupBy(i => (i.Id, i.Version))
  .Select(g => 
    g.OrderBy(i => i.Status.HasValue ? 1 : 2)
      .ThenByDescending(i => i.DateModified)
      .First() 
  );

which you may prefer

  •  Tags:  
  • Related