我有一个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。对不起,我在上面更正了文件编号
答案 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();