在集合上使用Distinct()时的排除顺序

时间:2010-05-11 18:32:39

标签: c# collections

如果我的收藏按日期排序,则Distinct()会取相邻复制品列表中的第一个对象,还是不确定?我使用的IEqualityComparer不考虑日期字段,但我想确保始终采用最新日期。

4 个答案:

答案 0 :(得分:5)

您应该使用GroupBy

from s in whatever
group s by new { s.Field1, s.Field2 } into g
select g.OrderByDescending(o => o.Date).First()

编辑:您还可以将IEqualityComparerGroupBy一起使用:

whatever.GroupBy(
    s => s,      //Key
    g => g.OrderByDescending(o => o.Date).First()  //Result
    new MyComparer()
);

答案 1 :(得分:2)

没有定义它需要。

在实践中,如果您使用LINQ到对象,它可能会采取第一个,但您不应该依赖它。

如果你访问数据库,它取决于数据库版本,查询计划等。那么你真的不应该依赖它总是返回第一个。

如果您需要此保证,可以使用morelinq中的DistinctBy并向Jon Skeet询问guarantee the order for you

答案 2 :(得分:1)

this answer的评论中,Marc Gravell和我讨论了Enumerable.Distinct方法。判决结果是保留了订单,但文档并不能保证这一切始终有效。

答案 3 :(得分:1)

Enumerable.Distinct没有定义返回哪个值 - 但我看不出返回第一个以外的任何内容是否明智。同样,虽然订单未定义,但按照它们在原始序列中出现的顺序返回项目是明智的。

我通常不喜欢依赖于未指明的行为,但我认为这种情况发生变化的可能性极小。这是保留一套你已经返回的东西的自然行为,并在你看到一个新项目后立即产生结果。

如果您希望依赖此未指定的行为,则应在使用Distinct之前按日期(降序)对项目进行排序。或者,您可以使用分组,然后适当地对每个组进行排序。