Может ли FileSystemEnumerableIterator напрямую использовать StrCmpLogicalW для выполнения логической сортировки? - PullRequest
0 голосов
/ 10 ноября 2018

Есть ли способ напрямую использовать функцию StrCmpLogicalW Win32 при получении списка файлов из папки? Мне нужно сделать логическую сортировку, где первые числовые цифры рассматриваются как числа.

Встроенная функция OrderBy<> и OrderByDescending<> выполняют сортировку на основе символов.

В приведенном ниже коде я копирую коллекцию в список, а затем выполняю сортировку. Это работает, но это кажется дополнительным шагом .//

/// <summary>
/// Descending logical sort for lists with numeric data
/// </summary>
public class StrCmpLogicalDescendingComparer : Comparer<string>
{
  [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
  private static extern int StrCmpLogicalW(string x, string y);

  public override int Compare(string x, string y)
  {
    // Provide elements in reverse order to sort descending
    return StrCmpLogicalW(y, x);
  }
}

/// <summary>
/// Examine folder and return the next file number in sequence
/// </summary>
/// <param name="folder"></param>
/// <returns></returns>
private int FindNextFileNumber(string folder)
{
  int result = -1;
  // Return an array of file names from the folder

  // Original attempt, does a character sort
  //var files = Directory.EnumerateFiles(folder)
  //              .OrderByDescending(filename => filename);

  var files = Directory.EnumerateFiles(folder);
  if (files.Count() > 0) {
    // Convert the collection to a list that can use the logical sorter
    List<string> sortableList = files.ToList();//= new List<string>();
    sortableList.Sort(new StrCmpLogicalDescendingComparer());
    foreach (string file in sortableList) {
      // Files with alpha will not qualify as a number, loop will
      // keep trying until it finds the highest number
      if (Int32.TryParse(Path.GetFileNameWithoutExtension(file), out result)) {
        result++;
        break;
      }
    }
  }
  // Check to see if there were any numeric files found
  if (result == -1) {
    result = 0;
  }
  return result;
}

1 Ответ

0 голосов
/ 10 ноября 2018

Прямо сейчас вы заказываете потенциально большой список файлов, когда вас интересуют, может быть, только несколько, что кажется расточительным; представьте тысячи буквенно-цифровых имен и только несколько числовых ... ой. Почему бы не отфильтровать сначала файлы, которые не являются числами, а , а затем заказать остальные?

Важным дополнительным преимуществом этого подхода является то, что, как только вы знаете , у вас есть только числовые имена файлов, тривиально правильно упорядочить их, не возвращаясь к собственным функциям:

static int FindNextFileNumber(string folder)
{
    var i = 0;

    return Directory.EnumerateFiles(folder)
                    .Where(f => int.TryParse(f, out i))
                    .Select(f => i)
                    .OrderByDescending(n => n)
                    .FirstOrDefault();
}
...