2016-02-25 1 views
1

Я выбираю все файлы в папке и добавляю имена всех файлов в 2 списка. xmlFilePath и listVersionКак добавить файлы в список после заказа по его названию?

В примере мои имена файлов являются, как показано ниже

1.8.1 

1.8.2 

1.10.0 

1.10.1 

но следующий код добавьте его имя, как показано ниже.

1.10.0, 1.10.1, 1.8.1, 1.8.2 

Я хочу изменить свой порядок ниже (приказ по его имени)

1.8.1, 1.8.2, 1.10.0, 1.10.1, 

Как я могу достичь этого требования?

FolderBrowserDialog folderDlg = new FolderBrowserDialog(); 
DialogResult result = folderDlg.ShowDialog(); 

if (result == DialogResult.OK) 
{ 
    string[] files = Directory.GetFiles(folderDlg.SelectedPath); 
    lblFolder.Text = "Folder : " + folderDlg.SelectedPath; 
    lblFiles.Text = "No of Xml Found : " + files.Length.ToString(); 

    try 
    { 
     foreach (string filePath in Directory.GetFiles(folderDlg.SelectedPath)) 
     { 
      xmlFilePath.Add(filePath); 
     } 

     foreach (string file in files) 
     { 
      string fileName = Path.GetFileNameWithoutExtension(file); 
      listVersion.Add(fileName); 
     } 
    } 
    catch (System.Exception ex) 
    { 
     lbl_notifications.Text = ex.Message; 
    } 
} 
+0

этих цифр выглядит как семантический номер версии, на заказ, используя semver взглянуть на [этот ответ] (HTTP: //codereview.stackexchange.com/questions/106660/convert-an-object-to-an-ordered-by-semver-markdown-list). – harishr

ответ

0

Похоже, вы боретесь со строками, представляющими версии.

Вы можете преобразовать их в свою версию и отсортировать их.

var sortedVersions = files.Select(x => new Version(x)).OrderBy(x => x); 

Теперь вы можете использовать sortedVersions или преобразовать его обратно в массив строк.

files = sortedVersions.Select(x => x.ToString()).ToArray(); 

Вы можете посмотреть на Version класс и использовать его, если он подходит лучше. Работа со строками является рискованной, и вы можете уменьшить этот риск, используя соответствующий тип данных.

Если имена файлов начинаются с "v_", вы можете изменить приведенный выше код и обработать его.

var sortedVersions = files.Select(x => new Version(x.Substring(2))).OrderBy(x => x); 
files = sortedVersions.Select(x => "v_" + x.ToString()).ToArray(); 
1

Проблема в том, что это сортировка имени в виде текста без уважения к числовому значению элементов. В тексте «1» меньше, чем «8», и не имеет значения, что за «1» следует «0».

ли это:

string[] files = Directory.GetFiles(folderDlg.SelectedPath); 
files = files.OrderBy(f => int.Parse(f.Split(".")[0])) 
       .ThenBy(f => int.Parse(f.Split(".")[1])) 
       .ThenBy(f => int.Parse(f.Split(".")[2])).ToArray(); 

Вы можете улучшить это далее, создавая .Select() проекции в начале, который включает имя файла и разделение части, так что вам не придется держать повторное Split() -в одной строке, но это должно хотя бы работать.

1

Если имена файлов на самом деле версии сортировать их версии:

string[] files = Directory.GetFiles(folderDlg.SelectedPath); 

    Array.Sort(files, (left, right) => 
    new Version(Path.GetFileNameWithoutExtension(left)).CompareTo(
    new Version(Path.GetFileNameWithoutExtension(right)))); 

Edit: в общем случае, например, имена, как "v_1.2.4 bla-bla-bla 5.6.7" вы можете использовать StrCmpLogicalW функции (как File Explorer делает) или его аналог

using System.Runtime.InteropServices; 

... 

[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] 
private static extern int StrCmpLogicalW(string x, string y); 
... 

string[] files = Directory.GetFiles(folderDlg.SelectedPath); 

Array.Sort(files, (left, right) => StrCmpLogicalW(
    Path.GetFileNameWithoutExtension(left), 
    Path.GetFileNameWithoutExtension(right))); 
+0

Да .. это действительно работает. если я использую имя файла как «v_1.8.1», он выдает ошибку под названием «Строка ввода не в правильном формате." Как использовать это решение для имен файлов такого типа? – Sachith

+0

@Sachith - Если имена ваших файлов начинаются с' 'v_" ', то вы должны были упомянуть об этом в своем вопросе. – Enigmativity

+0

@Sachith: в общем случае я предлагаю используя функцию 'StrCmpLogicalW' (или ее аналог). См. мое редактирование –