【问题标题】:How to find duplicates and preserve the later entry如何查找重复项并保留以后的条目
【发布时间】:2021-09-19 18:34:27
【问题描述】:

我有两个来自不同来源的对象列表,如下所示:

public class PersonToolDto {
   public int PersonId { get; set; }

   public int ToolId { get; set; }

   public DateTime CreatedAt { get; set; }
}

var personToolListFromSomeSource = new List<PersonToolDto>{
     new PersonTool{1, 1, 2021-07-07},
     new PersonTool{2, 1, 2021-07-07},
     new PersonTool{3, 1, 2021-07-07},
}

var personToolListFromAnotherSource = new List<PersonToolDto>{
     new PersonTool{1, 1, 2021-06-07},
     new PersonTool{2, 1, 2021-07-07},
     new PersonTool{3, 1, 2021-07-07},
}

我想消除重复项,只保留最新条目。使用 linq 或其他方法来实现这一目标的简单快速的方法是什么?一个人的简单 groupby by id 不会消除重复,我有点迷失如何比较日期。

我想保留结构并继续使用列表。

【问题讨论】:

    标签: c# list linq duplicates compare


    【解决方案1】:

    您可以执行以下操作:

    var withoutDuplicates = personToolListFromSomeSource
        .Concat(personToolListFromAnotherSource)
        .GroupBy(p => new { p.PersonId, p.ToolId })
        .Select(g => g.OrderByDescending(x => x.CreatedAt).First())
        .ToList();
    

    【讨论】:

    • 也可以使用GroupBy重载来消除选择:.GroupBy(p =&gt; new { p.PersonId, p.ToolId }, (k,v)=&gt;v.OrderByDescending(x =&gt; x.CreatedAt).First())
    • 另外,看起来 OP 只希望通过 PersonId 区分,而不是 PersonId 和 ToolId
    【解决方案2】:

    对于即将推出的 .NET 6,您还可以使用新的DistinctBy

    var output = personToolListFromSomeSource
        .Concat(personToolListFromAnotherSource)
        .OrderByDescending(x => x.CreatedAt)
        .DistinctBy(x => x.PersonId)
        .ToList(); 
    

    .NET 6 也有一个MaxBy,所以另一种选择是:

    var output = personToolListFromSomeSource
        .Concat(personToolListFromAnotherSource)
        .GroupBy(x => x.PersonId, (k,v) => v.MaxBy(x => x.CreatedAt))    
        .ToList();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-15
      • 2020-07-08
      • 1970-01-01
      相关资源
      最近更新 更多