Как использовать LINQ, чтобы упорядочить имя файла по подстроке, используя условие? - PullRequest
0 голосов
/ 08 января 2019

У меня есть несколько файлов Excel (.xlsx) в папке и ее подпапках, которые я пытаюсь перечислить на моем веб-сайте. Имена файлов имеют следующий формат:

2018_MyData_Day.xlsx
2018_MyData_Month.xlsx
2018_MyData_Year.xlsx
2019_MyData_Day.xlsx
2019_MyData_Month.xlsx
2019_MyData_Year.xlsx

Примечание: Day, Month и Year - это текст, а не заполнитель для фактического числового дня, месяца или года (в случае, если это вводило в заблуждение).

Мне нужно отобразить эти имена файлов по убыванию имен файлов, но сгруппированных по Year, Day или Month в указанном порядке. Итак, вывод, используя список выше, должен быть:

2019_MyData_Year.xlsx
2018_MyData_Year.xlsx

2019_MyData_Day.xlsx
2018_MyData_Day.xlsx

2019_MyData_Month.xlsx
2018_MyData_Month.xlsx

Я использовал следующее для сортировки имени файла по году и по подстроке Day, Month, Year, но подстрока не упорядочена правильно:

var fileGroup = (
    from file in Directory.EnumerateFiles(myPath, searchPattern: "*.xlsx", searchOption: SearchOption.AllDirectories)
    let fileName = Path.GetFileName(file)
    orderby fileName descending
    select fileName
).OrderBy(f => f.Substring(f.LastIndexOf("_")))

Я уверен, что мне нужно условие, так как желаемый заказ является индивидуальным, но я не уверен, как его реализовать.

Возможно ли это вообще или есть лучший способ достичь желаемого результата?

Спасибо!

Ответы [ 6 ]

0 голосов
/ 08 января 2019

Вы можете попробовать изменить свой код, чтобы он стал:

var fileGroup = (
from file in Directory.EnumerateFiles(myPath, searchPattern: "*.xlsx", searchOption: SearchOption.AllDirectories)
let fileName = Path.GetFileName(file)
let fileParts = fileName.Split('.')[0].Split('_')
orderby fileParts[2] descending, fileParts[0] descending
select fileName
)
0 голосов
/ 08 января 2019

Вы можете использовать LINQ следующим образом.

var list = new []{
    "2018_MyData_Day.xlsx",
    "2018_MyData_Month.xlsx",
    "2018_MyData_Year.xlsx",
    "2019_MyData_Day.xlsx",
    "2019_MyData_Month.xlsx",
    "2019_MyData_Year.xlsx"
     };

    var result = list.GroupBy(x=> new { Type= x.Split(new[]{"_"},StringSplitOptions.RemoveEmptyEntries)[2]})
                     .Select(x=> new {Key = x.Key, FullName = x.OrderBy(c => c)});
0 голосов
/ 08 января 2019
IEnumerable<string> files = Directory.EnumerateFiles(myPath, searchPattern: "*.xlsx", searchOption: SearchOption.AllDirectories).Select(x => Path.GetFileName(x));

Regex reg = new Regex(".*_(?<dmy>Day|Month|Year)\\.xlsx");
var groups = files.GroupBy(x => reg.Match(x).Groups["dmy"].Value);
StringBuilder builder = new StringBuilder();
foreach (var g in groups.OrderBy(x => x.Key == "Year" ? 0 : x.Key == "Day" ? 1 : 2))
{
    builder.AppendLine();
    foreach(var f in g.OrderByDescending(x => x))
    {
        builder.AppendLine(f);
    }
}
0 голосов
/ 08 января 2019

Вы можете легко сделать это, используя несколько let:

var fileGroup = (from f in Directory.GetFiles(myPath, "201*.xlsx")
                let fName = Path.GetFileNameWithoutExtension(f)
                let ymd = fName.Substring("2000_MyData_".Length).ToLower()
                 let fOrder = (ymd == "year" ? 0 : ymd == "day" ? 1 : 2)
                 select new {f, year=int.Parse(fName.Substring(0,4)), o=fOrder})
                .OrderBy(g => g.o)
                .ThenByDescending(g => g.year)
                .Select(g => g.f);
0 голосов
/ 08 января 2019
 var fileGroup = (from file in Directory.EnumerateFiles(myPath, searchPattern: "*.xlsx", searchOption: SearchOption.AllDirectories)
            let fileName = Path.GetFileName(file)
            select fileName)
            .GroupBy(f => f.Substring(f.LastIndexOf("_") + 1))
            .Select(x => x.OrderBy(y => y));

Думаю, это решит вашу проблему.

0 голосов
/ 08 января 2019

Почему бы не использовать Select, когда вы проецируете имя файла на два свойства:

  • FileYear: 2018, 2019, все до первого подчеркивания
  • FilePeriod: int, где (0) = год, (1) = день, (2) = месяц, часть после второго подчеркивания

.

var underscore = new char[] {'_'};
var orderedFiles = originalFiles.Select(fileName =>
{
    // TODO: decide what to do if filename incorrect format
    var splitFileName = fileName.Split(underscore);

    int filePeriod;
    switch (splitFileName[2])
    {
        case "Year":
            filePeriod = 0;
            break;
        case "Day":
            filePeriod = 1;
            break;
        case "Month":
            filePeriod = 2;
            break;
        default:
            filePeriod = 3;
            break;
    }

    return new
    {
        FileYear = Int32.Parse(splitFileName[0]),
        FilePeriod = filePeriod,
        OriginalFileName = fileName,
    };
})

// sort:
.OrderBy(splitFile => splitFile.FileYear)
.ThenBy(splitFile => splitFile.FilePeriod)

// back to original filename
.Select(splitFile => splitFile.OriginalFileName);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...