2015-09-25 93 views
6

我有一个包含多个属性的对象列表。这是对象。根据分组删除除列表中的所有对象

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进行分组时,我试图按扫描日期排序,然后只保留多次扫描的最后扫描日期。

这里是2个机一些测试数据:

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 
+1

你知道你可以做一个只读自动属性并摆脱后台字段'公共字符串UniqueId {获取;私人设置; }'。 – juharr

+0

您还应该获得该测试数据的预期结果。 – juharr

回答

5

我想删除已扫描当天,除了对给定机器最后一个任何数据点。

所以我假设你想同时使用ScanDateScannerID。下面是代码:

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

它会命令'ScanDate',所以你可以使用'Last'? – ieaglle

+0

这将根据'ScanDate'和'ScannerID'进行分组,如果最后一个表示最后输入的值,那么这就足够了,但如果他是按日期排列的最后一个,那么我必须编辑我的答案。 –

+1

我认为你实际上希望在'i.ScanDate.Date'上进行分组,因为OP表示_scanned在同一天_。然后按'ScanDate'命令。 – juharr

-1

正如顺便说一句,这个类可能是,如果我理解你正确地这是你想要的东西定义为

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; } 

}

+1

这真的应该是一个评论,而不是一个答案。有点像我已经提出的评论。 – juharr

+0

@juharr,对不起,我在添加评论时正在输入内容。但是,我想在需要的地方展示更少的代码行,这对于评论来说很重要。这就是为什么我在前面加上“就像旁边一样”。 –

1

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