通过列表中的两个属性选择distinct

use*_*444 24 c# linq-to-objects list distinct

我有一个list<message>包含类型GuidDateTime(以及其他属性)的属性.我想摆脱所有在列表中的项目,其中的GuidDateTime是相同的(除了一个).有时候这两个属性会与列表中的其他项目相同,但其他属性会有所不同,所以我不能只使用.Distinct()

List<Message> messages = GetList();
//The list now contains many objects, it is ordered by the DateTime property

messages = from p in messages.Distinct(  what goes here? ); 
Run Code Online (Sandbox Code Playgroud)

这就是我现在所拥有的,但似乎应该有更好的方法

List<Message> messages = GetList();

for(int i = 0; i < messages.Count() - 1)  //use Messages.Count() -1 because the last one has nothing after it to compare to
{
    if(messages[i].id == messages[i+1}.id && messages[i].date == message[i+1].date)
    {
        messages.RemoveAt(i+1);
    {
    else
    {
         i++
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 66

LINQ to Objects无法以内置方式轻松提供此功能,但MoreLINQ有一个方便的DistinctBy方法:

messages = messages.DistinctBy(m => new { m.id, m.date }).ToList();
Run Code Online (Sandbox Code Playgroud)

  • [现在在 .NET 6 中可用](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.distinctby?view=net-6.0),无需第三方依赖项或自定义扩展方法! (10认同)
  • @ user1304444:是的,我认为这是在撰写答案时,我决定启动MoreLINQ :) (4认同)
  • 对于其他观看此问题的人来说,Shyju上面提到的链接似乎也是一个很好的答案.http://stackoverflow.com/questions/489258/linq-distinct-on-a-particular-property (3认同)
  • @ user1304444:这是一个开源库 - 请参阅页面左侧的"Apache License 2.0"链接. (2认同)

Ada*_*dam 15

Jon Skeet DistinctBy肯定是要走的路,但如果你有兴趣定义自己的扩展方法,你可能会对这个更简洁的版本感兴趣:

public static IEnumerable<TSource> DistinctBy<TSource, TKey>
(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
    var known = new HashSet<TKey>();
    return source.Where(element => known.Add(keySelector(element)));
}
Run Code Online (Sandbox Code Playgroud)

它具有相同的签名:

messages = messages.DistinctBy(x => new { x.id, x.date }).ToList();
Run Code Online (Sandbox Code Playgroud)

  • 我知道这是旧的,但请注意,在调用`DistinctBy()`之后你必须调用`ToList()`或`ToArray()`.如果直接在`IEnumerable`上工作并多次枚举它将无法工作,因为这些项在第一次通过`IEnumerable`时被添加到`HashSet`中,并且不会再次返回,如[.NET Fiddle](https://dotnetfiddle.net/5PUJxl)所示. (5认同)