对文件夹名称数组进行排序,如 Windows 资源管理器(按数字和字母顺序)- VB.NET

问题描述 投票:0回答:3

为了让这个数组排序,我正在自杀和脱水。

我有一个包含以下生成的目录的数组;

暗淡文件夹()作为字符串= 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谢谢。

c# .net vb.net arrays sorting
3个回答
39
投票

您需要实现一个 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

1
投票

Array.Sort 也有一个 IComparer 参数,如果您不喜欢默认值,您可以覆盖排序行为。请参阅 Array.Sort 方法 (T[], IComparer) 如何操作


0
投票

如果有人不想使用 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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.