如何使用字段名称的子部分通过表达式指定双顺序
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('.')
,并在最终分组之前进行所有排序。
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('.')
,并在最终分组之前进行所有排序。