首页 > 解决方案 > 根据属性字符串过滤列表对象

问题描述

我有一个 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)
    ;

标签: c#linq

解决方案


您是正确的,第一select条语句阻止您维护原始对象。我的建议是按第二个元素对集合进行分组(你称之为 this 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


推荐阅读