如何在特定属性上使用Distinct并根据谓词选择要保留的对象?

时间:2016-06-28 19:44:22

标签: c# .net linq

我有ListDocument个对象。 Document类有许多属性,但这里只有两个属性相关,DocumentLinkIdUploadedOnDate

我想要做的是过滤列表,这样就没有两个Document个对象具有相同的DocumentLinkId。当有多个具有特定Document的{​​{1}}个对象时,我希望保留具有最新DocumentLinkId的对象。

我最初的倾向是做这样的事情:

UploadedOnDate

myDocumentsList.Distinct(d => d.DocumentLinkId).Max(d => d.UploadedOnDate); 不接受谓词。有没有办法用LINQ做到这一点?

3 个答案:

答案 0 :(得分:8)

您可以按DocumentLinkId对文档进行分组,对于每个组,请选择包含最新UploadedOnDate的项目,如下所示:

var result = myDocumentsList
    .GroupBy(d => d.DocumentLinkId)
    .Select(g => g.OrderByDescending(d => d.UploadedOnDate).First())
    .ToList();

答案 1 :(得分:1)

您可以使用this question中的DistinctBy

  

var query = people.DistinctBy(p => p.Id);

这将是:

myDocumentsList.OrderByDescending(x => x.UploadedOnDate).ToList().DistinctBy(d => d.DocumentLinkId).Max(d => d.UploadedOnDate);

适用于您的情况。

答案 2 :(得分:1)

您可以定义IEqualityComparer<Document>的实施。它几乎存在于这种情况下。

public class DocumentLinkIdDocumentEqualityComparer : IEqualityComparer<Document>
{
    public bool Equals(Document document1, Document document2)
    {
        return document1.DocumentLinkId == document2.DocumentLinkId;
    }
}

然后你可以这样做:

myDocumentsList.OrderByDescending(d => d.UploadedOnDate)
    .Distinct(new DocumentLinkIdDocumentEqualityComparer())

(不得不编辑它以先订购它,以便distinct返回具有最新日期的那个。)

您说,为了进行这一次Distinct比较,请使用此比较器,并将其视为具有相同DocumentLinkId的任何两个文档相同。

有什么好处是你不必修改Document来覆盖Equals,特别是因为这种特殊的相等比较可能不适用于所有情况。这使您可以指定何时使用特定的自定义相等比较。