为了让这个数组排序,我正在自杀和脱水。
我有一个包含以下生成的目录的数组;
暗淡文件夹()作为字符串= Directory.GetDirectories(RootPath)
我需要对它们进行排序,以便它们看起来像在 win7 / vista 中的 Windows 资源管理器中。 -- 按文件夹名称按数字和字母顺序排列。
文件夹名称同时包含字母和数字,有时仅包含字母或仅包含数字。
简单的 Array.Sort(Folders) 结果
C:\inetpub\wwwroot\rootpath\1
C:\inetpub\wwwroot\rootpath\10
C:\inetpub\wwwroot\rootpath\100
C:\inetpub\wwwroot\rootpath\1004
C:\inetpub\wwwroot\rootpath\101
C:\inetpub\wwwroot\rootpath\11
C:\inetpub\wwwroot\rootpath\12
C:\inetpub\wwwroot\rootpath\2
C:\inetpub\wwwroot\rootpath\3
C:\inetpub\wwwroot\rootpath\4
C:\inetpub\wwwroot\rootpath\5
C:\inetpub\wwwroot\rootpath\6
C:\inetpub\wwwroot\rootpath\7
C:\inetpub\wwwroot\rootpath\8
C:\inetpub\wwwroot\rootpath\87skjnd
C:\inetpub\wwwroot\rootpath\89sdf93kmw3
C:\inetpub\wwwroot\rootpath\9
C:\inetpub\wwwroot\rootpath\ad
C:\inetpub\wwwroot\rootpath\bin
C:\inetpub\wwwroot\rootpath\dark
C:\inetpub\wwwroot\rootpath\erk
C:\inetpub\wwwroot\rootpath\jkh23978yoaslkd3
C:\inetpub\wwwroot\rootpath\lk2309as
C:\inetpub\wwwroot\rootpath\work
C:\inetpub\wwwroot\rootpath\zone
我想要的(以及 Windows 资源管理器显示的内容)是...
C:\inetpub\wwwroot\rootpath\1
C:\inetpub\wwwroot\rootpath\2
C:\inetpub\wwwroot\rootpath\3
C:\inetpub\wwwroot\rootpath\4
C:\inetpub\wwwroot\rootpath\5
C:\inetpub\wwwroot\rootpath\6
C:\inetpub\wwwroot\rootpath\7
C:\inetpub\wwwroot\rootpath\8
C:\inetpub\wwwroot\rootpath\9
C:\inetpub\wwwroot\rootpath\10
C:\inetpub\wwwroot\rootpath\11
C:\inetpub\wwwroot\rootpath\12
C:\inetpub\wwwroot\rootpath\87skjnd
C:\inetpub\wwwroot\rootpath\89sdf93kmw3
C:\inetpub\wwwroot\rootpath\100
C:\inetpub\wwwroot\rootpath\101
C:\inetpub\wwwroot\rootpath\1004
C:\inetpub\wwwroot\rootpath\ad
C:\inetpub\wwwroot\rootpath\bin
C:\inetpub\wwwroot\rootpath\dark
C:\inetpub\wwwroot\rootpath\erk
C:\inetpub\wwwroot\rootpath\jkh23978yoaslkd3
C:\inetpub\wwwroot\rootpath\lk2309as
C:\inetpub\wwwroot\rootpath\work
C:\inetpub\wwwroot\rootpath\zone
我搜索了一下,发现需要编写一个类,使用 IComparable 对元素进行排序。作为一个超级新手……我真的不知道该怎么办。我看过的大多数示例都有多维数组和键:S ...
如果排序可以应用于文件名数组(而不是文件夹名称)或包含文件夹和文件的数组,那就更好了……在这种情况下,排序的文件夹出现在顶部,排序的文件显示在下面……是这可能吗?
任何帮助将不胜感激......:D谢谢。
您需要实现一个 IComparer,而不是创建一个实现 IComparable 的类。区别在于 IComparer 具有比较两个对象所需的“知识”,而 IComparable 是由知道如何将自身与其他对象进行比较的类实现的。
Windows 资源管理器对文件名进行排序的方式是使用名为 StrCmpLogicalW 的函数。您可以在自己的 IComparer 中使用此函数来获得与 Windows 资源管理器相同的排序行为。此函数将字符串的数字部分视为数字,以便 9 排在 10 之前。
public class MyComparer : IComparer<string> {
[DllImport("shlwapi.dll", CharSet=CharSet.Unicode, ExactSpelling=true)]
static extern int StrCmpLogicalW(String x, String y);
public int Compare(string x, string y) {
return StrCmpLogicalW(x, y);
}
}
Array.Sort(unsortedNames, new MyComparer());
因为我刚刚注意到这个问题被标记为 VB...请原谅我生锈的 VB!
Public Class MyComparer
Implements IComparer(Of String)
Declare Unicode Function StrCmpLogicalW Lib "shlwapi.dll" ( _
ByVal s1 As String, _
ByVal s2 As String) As Int32
Public Function Compare(Byval x as String, Byval y as String) As Integer _
Implements System.Collections.Generic.IComparer(Of String).Compare
Return StrCmpLogicalW(x, y)
End Function
End Class
Array.Sort 也有一个 IComparer 参数,如果您不喜欢默认值,您可以覆盖排序行为。请参阅 Array.Sort 方法 (T[], IComparer) 如何操作
如果有人不想使用 DllImport,那么这里是另一个 C# 代码来比较文件路径并根据文件系统对它们进行排序...
class FilePathStringComparer : IComparer<string>
{
public int Compare(string x, string y)
{
if (x.Length == y.Length)
return string.Compare(x, y);
else if (x.Length > y.Length)
return 1;
else
return -1;
}
}