【问题标题】:C# list of files name comparisonC# 文件名比较列表
【发布时间】:2016-11-22 07:27:00
【问题描述】:

对于我的编码技能,我有一个简单但非常艰巨的任务。

基本上我有一个任务来解析特定文件夹中的所有文件名(这执行得很好),但是我必须比较这些文件名并选择文件名特定部分中具有最新(最大)数字的文件名。一个例子:

0074-105-NVK.1.p7.ver.1.pdf
0074-105-NVK.1.p7.ver.2.pdf
0074-105-NVK.1.p7.ver.3.pdf

我感兴趣的部分是“ver.1”程序应该从中选择最高的文件并删除其他文件的部分。而且我真的不知道如何实现这个文件名比较。

【问题讨论】:

标签: c# filenames


【解决方案1】:

我建议借助正则表达式提取版本信息并按此版本排序:

  string[] files = new string[] {
     "0074 - 105 - NVK.1.p7.ver.1.pdf",
     "0074 - 105 - NVK.1.p7.ver.2.pdf",
     "0074 - 105 - NVK.1.p7.ver.3.pdf", };

  string pattern = @"ver\.(?<version>[0-9]+(\.[0-9]+)*)[^0-9]+$";

  var result = files
    .Select(file => new {
      name = file,
      ver = new Version(Regex.Match(file, pattern).Groups["version"].Value + ".0")
    })
    .OrderByDescending(item => item.ver)
    .Select(item => item.name)
    .FirstOrDefault();

【讨论】:

  • 非常感谢德米特里,我只需要了解如何实现它的逻辑,你帮了我很多:) 干杯!
【解决方案2】:

您可以使用以下命令获取所有文件名:

string[] fileNames = Directory.GetFiles(@"d:\Dir\", "*.pdf").ToList();
List<string> nameOnly = new List<string>();
List<KeyValuePair<string, string>> bind = new List<KeyValuePair<string, string>>();

一旦您将所有文件名都列在列表中,您就可以将扩展名排除为:

foreach(var item in fileNames)
{ 
    var x = Regex.Match(item, @".*(?=\.)").Value;
    nameOnly.Add(x);
}

仅用于将每个名称与其文件名绑定:

foreach(var item in nameOnly)
{ 
    var x = Regex.Match(item, @".*(?=\.)").Value;
    bind.Add(new KeyValuePair<string, string>(x,item));
}

你可以得到最大数量的最终文件名:

var max = bind.OrderBy(x => x.Key);
var fileName = max.LastOrDefault().Value;

【讨论】:

    【解决方案3】:

    使用单个 lambda 行可以很好地完成:

    var s1 = "0074-105-NVK.1.p7.ver.1.pdf";
    var s2 = "0074-105-NVK.1.p7.ver.2.pdf";
    var s3 = "0074-105-NVK.1.p7.ver.3.pdf";
    var arr = new[] {s1, s2, s3};
    var latestVer = arr.OrderBy(s => int.Parse(s.Split('.')[s.Split('.').Length - 2])).Last();
    

    【讨论】:

      【解决方案4】:

      你应该在数组或列表中有文件名:

      var fileNames = new List<string>();
      // fill list with proper file names
      

      再看你的样本,你可以对这个列表进行排序(假设只有 ver.x 可以改变):

      list.Sort(); // you can use parametrized method which sort by part of string
      

      你也可以使用 SortedList(你已经自动排序了):

      var fileNames = new SortedList<string>();
      fileNames.Add(fileName.Substring(18), fileName);
      

      或者你可以使用 Linq:

      var sorted = fileNames.OrderBy(item => item.Substring(18)); // in that case you can use different parts of file name)
      

      【讨论】:

      • 如果字符串长度不同怎么办?
      【解决方案5】:

      试试这个代码:

             string[] files = new string[] {
                               "0074 - 105 - NVK.1.p7.ver.1.pdf",
                               "0074 - 105 - NVK.1.p7.ver.11.pdf",
                               "0074 - 105 - NVK.1.p7.ver.2.pdf", };
      
      
              var result = files.Select(f => new
              {
                  name = f,
                  ver = int.Parse((f.Substring(f.IndexOf(".ver") + 1).Split('.')[1]))
              })
                .OrderByDescending(x => x.ver)
                .Select(x => x.name)
                .FirstOrDefault();
      

      【讨论】:

      • 反例:String[] files = new string[] {"0074 - 105 - NVK.1.p7.ver.10.pdf", "0074 - 105 - NVK.1.p7.ver.9.pdf"};。预期"0074 - 105 - NVK.1.p7.ver.10.pdf",实际:"0074 - 105 - NVK.1.p7.ver.9.pdf";你必须使用 natural 排序,而不是 lexicographical one
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      相关资源
      最近更新 更多