1

フォルダには、これらのファイルがあります。Windowsエクスプローラーでの順序は次のとおりです。

  • input(1).jpg
  • input(2).jpg
  • 入力(101).jpg

これは私がフォルダからファイルを取得する方法です:

var files = Directory.GetFiles(inputImage, "*.*", SearchOption.TopDirectoryOnly);

ただし、順序は次のようになります。

  • input(1).jpg
  • 入力(101).jpg
  • input(2).jpg

私も試しました:Array.Sort(files);

ただし、順序は同じです。この順序でファイルをロードするにはどうすればよいですか。

  • input(1).jpg
  • input(2).jpg
  • 入力(101).jpg
4

7 に答える 7

2

ゼロが埋め込まれていない数値が埋め込まれていることを「認識」する方法で2つの文字列を比較するには、独自の比較を実装する必要があります。Explorerにはすでにこのロジックが含まれており、(コメントによると)これは公開されており、並べ替えメソッドに渡すことができるカスタム実装でP/InvokeStrCmpLogicalWを使用して呼び出すことができます。Comparer<string>

名前(つまりパターン)について他のすべてを知っている場合は、比較のために固定部分を簡単に取り除くことStrCmpLogicalWができますが、優れた一般的な実装が得られます。

もちろん、ファイルを作成するものをすべて制御している場合、より簡単なアプローチは、ファイル名を適切な桁数(5または6など)にゼロパディングすることです。

于 2012-06-18T14:56:43.807 に答える
2

Array.Sort(files)は、デフォルトでは、ファイル名を数値ではなくテキストとしてソートすることに注意してください。数値を解析してから、それらで並べ替えてみてください。

于 2012-06-18T15:00:05.383 に答える
2

さて、私はこのようなことを試してみます:

        var files = from file in directoryInfo.EnumerateFiles()
        .Where(f => f.Extension == ".jpg")
                    orderby ExtractNumber(file.Name) ascending
                    select file.FullName;
        return files.ToList<string>();

ここでは、(と)の間のファイル番号を抽出します。

private static object ExtractNumber(string p)
{
    int lenght = p.IndexOf(')') - p.IndexOf('(');
    return int.Parse(p.Substring(p.IndexOf('('), lenght - 1)); 
}

これを行うには効率的な方法があるはずですが、私の2セントだけです。

于 2012-06-18T15:05:07.140 に答える
2

簡単な方法でファイルをロードする場合:

string[] files = Directory.GetFiles ("folder");

括弧内に常に数字があると仮定すると、次の関数を使用できます。

Array.Sort (files, compareFilesWithBrackets);

比較機能付き:

public static int compareFilesWithBrackets (string arg1, string arg2)
{
        string filename1 = System.IO.Path.GetFileName (arg1); //extract filename from the path of the first file
        string filename2 = System.IO.Path.GetFileName (arg2); // extract second file filename
        Match m = Regex.Match (filename1, "\\(([0-9]+)\\)"); // check if there is (number) for file 1
        int file1 = 0; // if no number leave 0
        if (m.Success) { // else if success parse the number from brackets
            file1 = int.Parse (m.Groups [1].Value); 
        }
        m = Regex.Match (filename2, "\\(([0-9]+)\\)");
        int file2 = 0;
        if (m.Success) {
            file2 = int.Parse (m.Groups [1].Value); 
        }
        return file1 - file2;
}
于 2012-06-18T15:41:18.030 に答える
1

このCustomSortは役立ちます

List<string> list = new List<string>()
{
   "input (1).jpg","input (101).jpg", "input (11).jpg", "input (2).jpg"
};

var sortedList = list.CustomSort().ToList();

出力は次のようになります。

input (1).jpg
input (2).jpg
input (11).jpg
input (101).jpg

ここにコードをコピーします

public static class MyExtensions
{
    public static IEnumerable<string> CustomSort(this IEnumerable<string> list)
    {
        int maxLen = list.Select(s => s.Length).Max();

        return list.Select(s => new
        {
            OrgStr = s,
            SortStr = Regex.Replace(s, @"(\d+)|(\D+)", m => m.Value.PadLeft(maxLen, char.IsDigit(m.Value[0]) ? ' ' : '\xffff'))
        })
        .OrderBy(x => x.SortStr)
        .Select(x => x.OrgStr);
    }
}
于 2012-06-18T16:29:04.633 に答える
1

私の場合、辞書オブジェクトを作成し、最初の値を元のファイル名として保存し、2番目の値をマッサージする必要のあるカスタムファイル名として保存します。

したがって、たとえば、辞書オブジェクトは次のようになります。

input (1).jpg    |  input (001).jpg
input (2).jpg    |  input (002).jpg
input (101).jpg  |  input (101).jpg

次に、2番目のフィールドで並べ替えることができますが、辞書オブジェクトの最初のフィールドからファイル名を取得します。

于 2012-06-18T14:59:58.427 に答える
1

OrderBy拡張機能を使用できます。詳細については、http://msdn.microsoft.com/en-us/library/bb534966.aspxを参照してください。

これは、t=>t部分の単純なラムダ式です。必要に応じて、並べ替える前に操作を行うことができます。

var files = Directory.GetFiles(inputImage, "*.*", SearchOption.TopDirectoryOnly).OrderBy(t => t);

数字だけで並べ替えたい場合は、次のような巧妙な文字列置換を行うことができます。

.OrderBy(t => t.Replace("input", "").Replace("(", "").Replace(")","").Trim());
于 2012-06-18T15:03:12.307 に答える