【问题标题】:Sort list items [full path] by file name in C#在C#中按文件名对列表项[完整路径]进行排序
【发布时间】:2016-11-23 08:45:08
【问题描述】:

我有一个字符串类型的列表。每个字符串都是文件的完整路径。现在我想按文件名对这个列表进行排序。

当我使用 Sort() 方法时,列表将按完整路径排序。但路径可能不同。

有没有一种简单的方法可以按每个项目的最后一个 \ 之后的内容对列表进行排序?

【问题讨论】:

标签: c# list sorting


【解决方案1】:

您可以使用System.IO.Path.GetFileName 和 LINQ:

files = files.OrderBy(System.IO.Path.GetFileName).ToList();

如果您想以不区分大小写的方式进行比较,可以传递StringComparer

files = files.OrderBy(System.IO.Path.GetFileName, StringComparer.InvariantCultureIgnoreCase).ToList();

请注意,OrderBy(和OrderByDescending)使用稳定的排序算法,而不是List.Sort。这意味着所有相等的元素都保持原来的顺序。

【讨论】:

  • 此外,文件列表很可能可以从 Directory.EnumerateFiles() 获得,它可以与 OrderBy 一起使用 - 在这种情况下,这可以在对文件进行排序之前将文件临时存储在列表或数组中.
【解决方案2】:

您正在寻找Path.GetFileName

https://msdn.microsoft.com/en-us/library/system.io.path.getfilename(v=vs.110).aspx

   List<string> files = ...

   // when sorting via Sort we should compare file names
   files.Sort((left, right) => 
     string.Compare(Path.GetFileName(left), Path.GetFileName(right)));

Sort 相对于 Linq OrderBy 的优势是

  • 当 Linq 通过 .ToList() 创建附加集合时,Sort 执行 就地 排序
  • 您可以将复杂的排序算法放在 lambda 函数中;在 Linq 的情况下,必须实现 IComparer&lt;T&gt; 接口

缺点是

  • Sort 需要List&lt;T&gt; 时,Linq 只需要IEnumerable&lt;T&gt;
  • Sort() 使用不稳定排序算法(如果两个项目被认为相等,则无法保证它们在排序列表中的实际顺序)
  • 当前最简单的实现string.Compare(Path.GetFileName(left), Path.GetFileName(right)) 调用Path.GetFileName 过于频繁(大约是OrderBy 的两倍)

【讨论】:

  • 此尝试比其他尝试效果更好,因为您可以明确指定 CultureInfo 和 CompareOptions,例如String.Compare(Path.GetFileName(left), Path.GetFileName(right), CultureInfo.InvariantCulture, CompareOptions.Ordinal)
  • @Manfred Radlwimmer:另一个优点是Sort 对列表进行就地排序,而 Linq 会创建一个额外的集合
  • @ManfredRadlwimmer:您可以使用OrderBy 的重载来传递StringComparer。我已经相应地编辑了my answer
  • 使用OrderBy() 的一个主要缺点是每次比较都会调用Path.GetFileName() 两次,而OrderBy 只会为列表中的每个项目调用一次。比较的数量可以大大超过列表中的项目数量。
  • 另一个缺点是List.Sort 执行不稳定,而Enumerable.OrderBy 执行稳定排序。所以相等的项目保持原来的顺序。
【解决方案3】:

这个示例代码,

 var getFileName = System.IO.Path.GetFileName("C:\temp\name.txt"); > temp.txt

 var getfileNameWithoutExtention = System.IO.Path.GetFileName("C:\temp\name.txt"); > name

 var getextention = System.IO.Path.GetFileName("C:\temp\name.txt"); > .txt



 List<string> patsh = new List<string>
        {
            @"C:\temp\name.txt",
            @"C:\music\ranbow.mp3",
            @"C:\net\core.cs",
            @"C:\java\fr.jar"
        };



 patsh = patsh.OrderBy(System.IO.Path.GetFileNameWithoutExtension).ToList();

如果你想用文件扩展名来做

 patsh = patsh.OrderBy(System.IO.Path.GetFileNameWithoutExtension).ThenBy(System.IO.Path.GetExtension).ToList();

【讨论】:

    【解决方案4】:

    这可能对你有用

    List<string> fullfilepath = new List<string>() { "C:\\text1.txt", "C:\\text2.txt", "D:\\text4.txt", "C:\\text3.txt", "C:\\text6.txt", "D:\\text5.txt" };
    List<string> sortedfilename = fullfilepath.OrderBy(x => Path.GetFileName(x)).ToList();
    

    【讨论】:

    • 这与蒂姆的回答有何不同?
    【解决方案5】:

    你也可以像这样按文件名排序:

    fileName = path.Split('\').Last();
    

    【讨论】:

    猜你喜欢
    • 2012-11-19
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    • 2011-08-06
    相关资源
    最近更新 更多