C# 根据分组删除列表中除1个对象以外的所有对象

C# 根据分组删除列表中除1个对象以外的所有对象,c#,.net,linq,list,C#,.net,Linq,List,我有一个包含多个属性的对象列表。这是物体 public class DataPoint { private readonly string uniqueId; public DataPoint(string uid) { this.uniqueId = uid; } public string UniqueId { get { return this.uniqueId;

我有一个包含多个属性的对象列表。这是物体

public class DataPoint
{
    private readonly string uniqueId;
    public DataPoint(string uid)
    {
        this.uniqueId = uid;
    }

    public string UniqueId
    {
        get
        {
            return this.uniqueId;
        }
    }

    public string ScannerID { get; set; }

    public DateTime ScanDate { get; set; }
}
现在在我的代码中,我有一个巨大的列表,数百个也许几千个

每个数据点对象都属于某种类型的扫描仪,并且有一个扫描日期。我想删除在同一天扫描的所有数据点,但给定机器的最后一个数据点除外

我尝试如下使用LINQ,但没有成功。我仍然有许多重复的数据点

this.allData = this.allData.GroupBy(g => g.ScannerID)
                   .Select(s => s.OrderByDescending(o => o.ScanDate))
                   .First()
                   .ToList();`
我需要按扫描仪ID对数据点进行分组,因为可能有数据点在同一天扫描,但在不同的机器上。如果有多个数据点,我只需要一天的最后一个数据点

编辑澄清-我所说的最后一个数据点是指给定机器的给定扫描日期的最后一个扫描数据点。我希望这有帮助。因此,当按扫描仪ID进行分组时,我尝试按扫描日期进行排序,然后在多次扫描的情况下,仅将最后一次扫描日期保留数天

以下是两台机器的一些测试数据:

Unique ID   Scanner ID      Scan Date
A1JN221169H07  49374    2003-02-21 15:12:53.000
A1JN22116BK08  49374    2003-02-21 15:14:08.000
A1JN22116DN09  49374    2003-02-21 15:15:23.000
A1JN22116FP0A  49374    2003-02-21 15:16:37.000 
A1JOA050U900J  80354    2004-10-05 10:53:24.000 
A1JOA050UB30K  80354    2004-10-05 10:54:39.000 
A1JOA050UD60L  80354    2004-10-05 10:55:54.000 
A1JOA050UF80M  80354    2004-10-05 10:57:08.000 
A1JOA0600O202  80354    2004-10-06 08:38:26.000 
我想删除在同一天扫描的所有数据点,但给定机器的最后一个数据点除外

因此,我假设您希望同时按
ScanDate
ScannerID
进行分组。代码如下:

var result = dataPoints.GroupBy(i => new { i.ScanDate.Date, i.ScannerID })
                       .OrderByDescending(i => i.Key.Date)
                       .Select(i => i.First())
                       .ToList();

顺便说一句,这个类可以定义为

public class DataPoint
{
  public DataPoint(string uid)
  {
    UniqueId = uid;
  }

public string UniqueId {get; private set; }
public string ScannerID { get; set; }
public DateTime ScanDate { get; set; }

}如果我理解正确,这就是你想要的

var result = dataPoints.GroupBy(i => new { i.ScanDate.Date, i.ScannerID })
                       .Select(i => i.OrderBy(x => x.ScanDate).Last())
                       .ToList();

这将根据扫描仪id和日期进行分组(
SacnnerDate.Date
将时间部分归零),然后根据
ScanDate
对每个分组进行排序(因为这些组是同一天,所以将在时间上排序),并取最后一个。因此,对于每一天,您将为每个扫描仪获得一个结果,该扫描仪具有该特定日期的最新
ScanDate

您知道,您可以将其设置为只读自动属性,并删除备份字段
public string UniqueId{get;private set;}
。您还应该为该测试数据选择所需的结果。这实际上应该是一个注释,而不是答案。有点像我已经做的评论。@juharr,对不起,你添加评论时我正在打字。然而,我想展示在需要的地方代码行是多么少,这对于一个注释来说太大了。这就是为什么我在前面加了
作为旁白的原因。它会排序
ScanDate
,这样你就可以使用
Last
?这将根据
ScanDate
ScannerID
进行分组,如果最后一个是指最后输入的值,那么这就足够了,但如果他是指最后一个日期,然后我必须编辑我的答案。我想你真的想在
I.ScanDate.Date
上分组,因为OP说是在同一天扫描的。然后按
ScanDate
排序。如果
OrderByDescending
则为
第一个
,而不是
最后一个
;)对不起,我指的是按日期列出的最后一个数据点。我将编辑我的问题。非常感谢。