使用重复元素过滤数组

时间:2011-02-17 21:59:25

标签: c# .net arrays duplicates

我有一个FileInfo对象数组,其中包含我想要过滤的重复元素,即删除重复项,元素按上次写入时间使用自定义比较器排序。文件名的格式如下:

文件{数} {YYYMMDD} {HHMMSS}的.txt

我想知道的是,是否有一种优雅的方法可以过滤掉具有相同文件编号的两个文件,以便列表中只有最新的文件,即我的数组中有两个元素,其中包含以下文件名称:

file1_20110214_090020.txt

file1_20101214_090020.txt

我想保留 file1 的最新版本。我获取文件的代码如下:

 FileInfo[] listOfFiles = diSearch.GetFiles(fileSearch);
 IComparer compare = new FileComparer(FileComparer.CompareBy.LastWriteTime);
 Array.Sort(listOfFiles, compare);

感谢您的帮助。

更新:

忘了添加警告,有问题的程序正在使用.Net 2.0,所以不幸的是没有LINQ。对不起,我在上面更正了文件编号

2 个答案:

答案 0 :(得分:5)

使用LINQ,你可以这样做:

var listOfFiles = diSearch
                  .GetFiles(fileSearch)
                  .GroupBy(file => file.Name.Substring(file.Name.IndexOf('_')))
                  .Select(g => g.OrderBy(file => file.LastWriteTime).Last())
                  .ToArray();

如果您希望在上次写入时间内对这些文件进行排序,请在.OrderByDescending(file => file.LastWriteTime)来电之前加入ToArray

您当然可以使用更有效的技术从每个组中查找最新文件,例如使用MaxBy运算符。

修改

在.NET 2.0中,您可以从数组中构造Dictionary<string, List<FileInfo>>(键为'file-group'),然后从每个列表中提取最新文件字典的Values集合,以产生结果。

如果您使用的是C#3或更高版本,则另一种选择是使用LINQBridge,这样可以在针对.NET 2.0时使用LINQ to Objects。

答案 1 :(得分:0)

如果我理解正确,您希望确定最新文件由文件名(YYYYMMM等)确定,而不是由上次写入时间确定,并按文件ID写入时间分组。在这种情况下,这将起作用:

var mostRecentFiles = listOfFiles.GroupBy( f => f.Name.Substring(0, f.Name.IndexOf("_")))
                                 .Select( g => g.OrderByDescending( f => 
                                         { string[] s =f.Name.Split(new [] {'_', '.'}); return Convert.ToDecimal(s[1]+s[2]);}).First())
                                 .ToList();