我有一个FTPFileItems对象列表,我需要对这些文件进行排序并根据文件名中的“版本”获取最新版本。
class FtpFileInfo
{
string FileName;
DateTime FileDate;
long FileSize;
FtpFileType FileType;
}
每个对象中的文件名数据示例
FileName = "XXX_AE_V1_20160812132126.xml"
FileName = "XXX_AE_V2_20160912142126.xml"
FileName = "XXX_AE_V3_20161012152126.xml"
FileName = "XXX_AU_V1_20190213142439.xml"
FileName = "XXX_AU_V2_20190313142439.xml"
FileName = "XXX_AU_V3_20190413142439.xml"
FileName = "XXX_AU_V4_20190513142439.xml"
FileName = "XXX_BR_V1_20170828214049.xml"
FileName = "XXX_BR_V2_20170928214049.xml"
FileName = "XXX_BR_V3_20171028214049.xml"
FileName = "XXX_BR_V4_20171038214049.xml"
FileName = "XXX_BR_V6_20171048214049.xml"
我需要按国家对象将列表压缩到最高文件版本。因此,列表应该以这样的形式结束,但是完整的List对象只是显示文件名部分:
FileName = "XXX_AE_V3_20161012152126.xml"
FileName = "XXX_AU_V4_20190513142439.xml"
FileName = "XXX_BR_V6_20171048214049.xml"
这是我正在尝试的方法,但是我没有得到所需的东西。我由于选择而失去了原始对象,但没有获得最高版本号。
var res = xmlFileNames.Select(s => new
{
XXX = s.FileName.Split('_')[0],
Country = s.FileName.Split('_')[1],
Version = s.FileName.Split('_')[2],
FileDate = s.FileName.Split('_')[3]
})
.OrderByDescending(x => x.Version)
.OrderBy(x => x.Country)
;
答案 0 :(得分:2)
您正确的是,第一个select
语句正在阻止您维护原始对象。我的建议是将集合按第二个元素分组(您将其称为Country
)。然后选择具有最高版本的版本,如下所示。最后按国家订购。
files.GroupBy(x => x.FileName.Split(new char[] { '_' })[1])
.Select(x => x.OrderByDescending(y => y.FileName.Split(new char[] { '_' })[2]).First())
.OrderBy(x => x.FileName.Split(new char[] { '_' })[1]);
下面显示了一个完整的解决方案,并根据您的示例提供了一个示例集合。
List<FtpFileInfo> files = new List<FtpFileInfo>() {
new FtpFileInfo { FileName = "XXX_AE_V1_20160812132126.xml" },
new FtpFileInfo { FileName = "XXX_AE_V2_20160912142126.xml" },
new FtpFileInfo { FileName = "XXX_AE_V3_20161012152126.xml" },
new FtpFileInfo { FileName = "XXX_AU_V1_20190213142439.xml" },
new FtpFileInfo { FileName = "XXX_AU_V2_20190313142439.xml" },
new FtpFileInfo { FileName = "XXX_AU_V3_20190413142439.xml" },
new FtpFileInfo { FileName = "XXX_AU_V4_20190513142439.xml" },
new FtpFileInfo { FileName = "XXX_BR_V1_20170828214049.xml" },
new FtpFileInfo { FileName = "XXX_BR_V2_20170928214049.xml" },
new FtpFileInfo { FileName = "XXX_BR_V3_20171028214049.xml" },
new FtpFileInfo { FileName = "XXX_BR_V4_20171038214049.xml" },
new FtpFileInfo { FileName = "XXX_BR_V6_20171048214049.xml" },
};
IOrderedEnumerable<FtpFileInfo> orders = files.GroupBy(x => x.FileName.Split(new char[] { '_' })[1])
.Select(x => x.OrderByDescending(y => y.FileName.Split(new char[] { '_' })[2]).First())
.OrderBy(x => x.FileName.Split(new char[] { '_' })[1]);
foreach (FtpFileInfo order in orders) {
Console.WriteLine(order.FileName);
}
我收到的输出如下所示,与您提到的是所需的输出相匹配。
XXX_AE_V3_20161012152126.xml
XXX_AU_V4_20190513142439.xml
XXX_BR_V6_20171048214049.xml
答案 1 :(得分:0)
var res = xmlFileNames.Select(s => new
{
XXX = s.FileName.Split('_')[0],
Country = s.FileName.Split('_')[1],
Version = s.FileName.Split('_')[2],
FileDate = s.FileName.Split('_')[3]
})
.OrderByDescending(x => x.Version, StringComparer.Ordinal)
.OrderBy(x => x.Country)
;
答案 2 :(得分:0)
您可以尝试使用Select
范围将其定义为结果,但可以使用该范围避免为每个属性(性能)调用Slipt
。使用OrderBy
和ThenBy
,您将得到所需的排序。最后,使用ToList
方法可以使它成为一个通用的更好的结构(匿名对象列表)。
var res = xmlFileNames.Select(s =>
{
var a = s.Split('_');
return new
{
XXX = a[0],
Country = a[1],
Version = a[2],
FileDate = a[3]
};
})
.OrderByDescending(x => x.Version)
.ThenBy(x => x.Country)
.ToList();
答案 3 :(得分:0)