.NET: エクスプローラのソート順

.NET

現在、Vectorで公開を予定している趣味的なアプリがあるのですが、その作成過程で気が付いたことがあります。それは、エクスプローラのソート順がASCII順(辞書順)ではないということです。
a1.txtとa02.txtがあった場合、ASCII順なら0は1よりも前に来るので、a02.txt<a1.txtとなるはずです。ところがエクスプローラでは、数字の部分は数値としてソートするので、a1.txt<a02.txtとなっています。これは natural order sort(自然順ソート)と言われています。

詳しい情報は、「エクスプローラ ソート順」でググれば、たくさん出てきます。エクスプローラのソート順をASCII順に変更する方法も見つかります。 なぜ今まで気づかなかったのかわかりませんが、Windows7に変えてからずっとファイルを探しにくいという違和感はありました。いくつかの記事によると、WindowsXPからそうなったということなのですが、XPの時はそんな違和感を感じた記憶がありません。謎です。

で、本題です。.NETに限らず、ほとんどのプログラミング言語では、ソートといえばASCII順です。しかしアプリケーションによっては、これでは困ることがあります。ではどうすればnatural orderでソートできるのか。
英語のサイトになりますが、stackoverflowに記事があります。

まず、StrCmpLogicalWを使う方法が載っています。この方法だとちゃんとa02.txt<a1.txtになりますが、ソートするデータによっては、無限ループに陥ることが実際にあるそうです。

次に使えそうなのが、stackoverflowの記事の真ん中あたり、

public static int CompareNatural(string strA, string strB) {
    return CompareNatural(strA, strB, CultureInfo.CurrentCulture, CompareOptions.IgnoreCase);
}

public static int CompareNatural(string strA, string strB, CultureInfo culture, CompareOptions options) {
    CompareInfo cmp = culture.CompareInfo;
    ...
    else if (softResult != 0) {
        return softResult;
    }
    return 0;
}

のコードです。これも望み通りa1.txt<a02.txtになりました。ただし、この方法で無限ループに陥ることがないかどうかは検証していないので不明です。

また、.NETの大御所DOBON.NETにも記事があります。そこに掲載されているデータを上記コードで試したところ、やはりエクスプローラと同じ結果が出ました。

private void button1_Click(object sender, EventArgs e)
{
    string[] a = new string[] {"a 2.txt", "a01.txt", "a02.txt",
                               "a1 0.txt", "a1.txt", "a10.txt",
                               "a100.txt", "a11.txt", "a2.txt",
                               "a29b.txt", "a2b.txt", "a3.txt"};
    Array.Sort(a, CompareNatural);
    listBox1.Items.AddRange(a);
}

こんな感じで。


« »

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

« »