2016-08-11 65 views
2

我有一个类型X的列表。这包含字段,我只需要返回列表中的唯一记录。我需要使用包含时间戳的字段/属性(OIndex)之一并使用该属性对其进行过滤。清单是这样的:C#如何过滤列表并删除重复项?

> 2c55-Checked-branchDeb-20160501121315-05 
> 2c60-Checked-branchDeb-20160506121315-06 
> 2c55-Checked-branchDeb-20160601121315-07 
> 2c55-Checked-branchDeb-20160601141315-07 
> 2c60-Checked-branchDeb-20160720121315-08 

在上面的例子中,最后一个字段是recordId,所以我们有一个“07”的重复记录。时间戳是四个字段。所以我想获得所有的记录,除了第三个是重复的。记录“07”的最新版本是第四行。

我开始做代码,但挣扎。到目前为止:

List<X> originalRecords = GetSomeMethod(); //this method returns our list above 

var duplicateKeys = originalRecords.GroupBy(x => x.Record) //x.Record is the record as shown above "05", "06" etc 
         .Where(g => g.Count() > 1) 
         .Select(y => y.Key); 

现在我该怎么办?现在我有重复的键。 我想我需要再次通过OriginalRecords列表并查看它是否包含重复密钥。 然后在日期时间使用子字符串。将此存储在某个地方,然后删除不是最新的记录。并用过滤器保存原始记录。由于

+0

你能定义这个键:'2c55-Checked-branchDeb-20160501121315-05'吗? – FrankerZ

+0

你看过[Distinct](http://www.dotnetperls.com/distinct)linq扩展方法吗? –

+0

@FrankerZ没有记录本身不是一个关键 – user2906420

回答

7

你并不需要明确地找到重复的键,你可以简单地首先从每个组中选择:

var res == originalRecords 
    .GroupBy(x => x.RecordId) 
    .Select(g => g.OrderByDescending(x => x.DateTimeField).First()); 

没有为DateTimeField字段没有字段在你的代码。我只是有一个包含datetime和其他数据的字符串字段。该记录具有记录标识字段。

您可以在短划线上拆分记录,抓取日期时间部分并对其进行排序。您的日期/时间格式允许您按照字典顺序进行排序,因此您可以跳过解析日期。

假设没有破折号,并且所有字符串以相同的方式格式化,x.TextString.Split('-')[3]表达会给你记录的时间戳部分:

var res == originalRecords 
    .GroupBy(x => x.RecordId) 
    .Select(g => g.OrderByDescending(x => x.TextString.Split('-')[3]).First()); 
+1

他应该先按日期时间字段(Decending)进行排序,以确保g.First()正在拉取最新的字段。 – FrankerZ

+0

@FrankerZ谢谢! – dasblinkenlight

+0

@dasblinkenlight上面的代码将不起作用,因为记录不是来自表格,或者在代码中没有datetimefield字段。我只是有一个包含datetime和其他数据的字符串字段。该记录具有记录标识字段。希望它是有道理的。 – user2906420

0

这应该解决您的问题:

List<X> originalRecords = GetSomeMethod(); 
Dictionary<int, X> records = new Dictionary<int, X>(); 

foreach (X record in originalRecords) { 

    if(records[record.recordId] != null) { 
     if(records[record.recordId].stamp < record.stamp){ 
      records[record.recordId] = record; 
     } 
    } 
    else { 
     records[record.recordId] = record; 
    } 
} 

你的回答是records.Values

希望它可以帮助

+0

在这一行中设置'recordId':if(record [recordId]!= null){'? – FrankerZ

+0

是错误的.. record.recordId是对象的最后一个字段..我忘了宣布字典或者..我更新了我的帖子 – guijob

+0

@J。Guilherme感谢您的帮助,但记录是一个字符串,其中有时间戳。我真的需要使用substring和indexOf并提取时间戳,然后相互比较。 – user2906420