首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按降序(按日期)对列表的一部分进行排序,按升序对另一部分进行排序(按字母顺序)?

按降序(按日期)对列表的一部分进行排序,按升序对另一部分进行排序(按字母顺序)?
EN

Stack Overflow用户
提问于 2019-04-18 11:15:02
回答 2查看 180关注 0票数 6

我有一个控件,它显示选定文件夹中所有PDF的列表。大多数PDF的名称(例如,会议记录)都以日期开始。我希望这些PDF按降序显示,以便最近的PDF显示在顶部。

在同一个文件夹中,我也有一些PDF,其名称不包含日期(例如,策略)。我要按字母顺序排列这些文件。

下面是我所拥有的列表的一个例子,以及我希望它是如何排序的:

  • 2019-01-12会议minutes.pdf
  • 2018-11-19次会议agenda.pdf
  • 2018-06-02会议minutes.pdf
  • 2017年-12-13次会议agenda.pdf
  • 2017年-04-27次会议minutes.pdf
  • 隐私policy.pdf
  • 保障policy.pdf
  • 福利policy.pdf

以下是我尝试过的:

代码语言:javascript
复制
private void GenerateFolder()
{
    folder_path = Server.MapPath(BaseFolder);
    _folder_view = new StringBuilder();

    if (Directory.Exists(folder_path))
    {
        DirectoryInfo info = new DirectoryInfo(folder_path);
        FileInfo[] files = info.GetFiles().OrderByDescending(p => p.FullName).ToArray();

        foreach (FileInfo file in files)
        { 
            doStuff();
        }
    }

    folder_view.Text = _folder_view.ToString();
}

使用此代码,名称以日期开头的PDF按降序(按日期)排序,这正是我想要的。但是其他的PDF的名字不是以日期开头的,没有按照我想要的方式排序(按字母顺序)。有办法实现我的双重分类目标吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-18 12:30:10

我将创建一个自定义类,将文件名的日期和其余部分解析为分隔属性,然后可以使用OrderByDescendingThenBy对这些单独的属性进行排序。

代码语言:javascript
复制
public class ParsedFilename
{
    public ParsedFilename(string filename)
    {
        FullName = filename;
        if (filename.Length >= 12 &&
            DateTime.TryParse(filename.Substring(0, 10), out var date))
        {
            Date = date;
            Name = filename.Substring(11);
        }
        else
        {
            Date = null;
            Name = filename;
        }
    }

    public DateTime? Date { get; }
    public string Name { get; }
    public string FullName { get; }
}

你可以这样使用它:

代码语言:javascript
复制
var data = new List<string>(new[]
    {
        "2019-01-12 Meeting minutes.pdf",
        "Safeguarding policy.pdf",
        "2017-04-27 Meeting minutes.pdf",
        "2018-06-02 Meeting minutes.pdf",
        "2017-12-13 Meeting agenda.pdf",
        "Privacy policy.pdf",
        "Welfare policy.pdf",
        "2018-11-19 Meeting agenda.pdf"
    });

var parsedData = data.Select(d => new ParsedFilename(d));

var sortedData = parsedData.OrderByDescending(d => d.Date)
                           .ThenBy(d => d.Name);

var output = sortedData.Select(d => d.FullName);

它产生以下输出:

2019-01-12会议minutes.pdf 2018-11-19次会议agenda.pdf 2018-06-02会议minutes.pdf 2017年-12-13次会议agenda.pdf 2017年-04-27次会议minutes.pdf 隐私policy.pdf 保障policy.pdf 福利policy.pdf

根据目录中文件名的格式,您可能需要添加一些更健壮的解析。

票数 4
EN

Stack Overflow用户

发布于 2019-04-18 12:38:45

在一项评论中,LocEngineer建议(释义):

首先使用基于regex的技术,如this question的答案所示,确定以日期开头的文件名。然后生成两个部分列表,然后组合起来。

本着这一建议的精神,这里展示了一个可能的解决办法:

代码语言:javascript
复制
public void CustomFileNameOrderingDemo()
{
    var files = new[]
    {
        "2017-04-27 Meeting minutes.pdf",
        "2018-11-19 Meeting agenda.pdf",
        "2019-01-12 Meeting minutes.pdf",
        "2018-06-02 Meeting minutes.pdf",
        "2017-12-13 Meeting agenda.pdf",
        "Safeguarding policy.pdf",
        "Welfare policy.pdf",
        "Privacy policy.pdf",
    };

    var filesWithDates = FindFilesWithDates().OrderByDescending(f => f).ToList();
    var filesWithoutDates = files.Except(filesWithDates).OrderBy(f => f);
    var result = filesWithDates.Concat(filesWithoutDates);

    IEnumerable<string> FindFilesWithDates()
    {
        return files.Where(f => Regex.IsMatch(f, @"^[0-9]{4}-[0-9]{2}-[0-9]{2} "));
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55744831

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档