如何使用字段名称的子部分通过表达式指定双顺序

How to specify a double order by expression using sub part of field name

lamabda/linq 东西相当新。

我有一个目录,里面有很多文件。

我想根据文件名的子部分对所有这些文件进行分组和排序。

所以,例如我有这些文件:

group1.01,001.dat
group1.01.102.dat
group1.01.086.dat

group2.03,101.dat
group2.02.002.dat
group2.01.016.dat

我想要这样的结果:

group1.01,001.dat
group1.01.086.dat
group1.01.102.dat

group2.01.016.dat
group2.02.002.dat
group2.03,101.dat

现在,我已经成功地对我的文件进行了分组,只是不是它们的顺序。

注意:定义顺序先ss再fff 其中文件格式为:

groupname.ss.fff.dat

因此,要获取群组,我有以下代码:

var result = Directory.EnumerateFiles(min, "*.dat")
.Select(s => Path.GetFileNameWithoutExtension(s))
.GroupBy(s => (s.Split('.'))[0]).ToList();

效果很好。我认为通过添加这个可以完成我的工作:

var result = Directory.EnumerateFiles(min, "*.dat")
.Select(s => Path.GetFileNameWithoutExtension(s))
.GroupBy(s => (s.Split('.'))[0])
.OrderBy(s=> (s.Split('.'))[1] && s.Split('.'))[2]).ToList();

不编译。请问我需要做什么?

要指定次要排序标准,请使用 ThenBy:

var result = Directory.EnumerateFiles(min, "*.dat")
    .Select(fileName => Path.GetFileNameWithoutExtension(fileName))
    .OrderBy(name => name.Split('.')[1])
    .ThenBy(name => name.Split('.')[2])
    .GroupBy(name => name.Split('.')[0])
    .OrderBy(g => g.Key) // Note: g is an IGrouping<string, string>
    .ToList();

此代码在 分组之前按次要标准排序,利用GroupBy 保留序列中项目的原始顺序这一事实。然后按名称的第一个组成部分进行分组和排序。

这是使用 LINQ 查询语法的替代解决方案:

var result =
    from fileName in Directory.EnumerateFiles(min, "*.dat")
    let name = Path.GetFileNameWithoutExtension(fileName)
    let parts = name.Split('.')
    orderby parts[0], parts[1], parts[2]
    group name by parts[0] into g
    select g;

此代码略有不同,因为它只调用一次 name.Split('.'),并在最终分组之前进行所有排序。