首页 > 解决方案 > 如何使用 string.split 对具有特定格式的字符串列表进行排序?

问题描述

我收到的文件具有以下格式的文件名:

File_1242161_08112019010101PMFile_1710485_08112019111721AM

我需要按照字符串第三部分中的日期时间顺序处理这些文件。我还希望能够处理不遵循这种特定格式的文件,例如:

File_666840

我想将列表从最早的日期时间排序为最新的,如果没有日期时间,请移至按文件名排序的列表底部。我尝试了以下方法:

List<string> sorted = filenames.OrderByDescending(file => file.Name.Split('_').Count())
                .ThenBy(file => file.Name.Split('_').LastOrDefault().ToList());

这让我几乎一直到那里,但 AM/PM 没有正确排序。由于显而易见的原因,带有 01:01:01 PM 的文件名将在上午 11:17:21 之前显示。什么是完成我想要的最高效和最 LINQ 的方式?

标签: c#linq

解决方案


只需使用ParseExact格式 MMddyyyyhhmmsstt选择一个ValueTuple或其他东西。

将日期和时间的指定字符串表示形式转换为其等效的 DateTime。字符串表示的格式必须与指定的格式完全匹配,否则将引发异常。

由于现在分开了,您可以随意订购,这只是一个示例

给定

var list = new List<string>()
              {
                 "File_1242161_08112019010101PM",
                 "File_1710485_08112019111721AM",
                 "File_1710488",
                 "File_1710489",
                 "File_1710480"
              };

代码

var orderedList = list.Select<string, (string Value, DateTime? Date)>(
                          x =>
                             {
                                var results = x.Split('_');

                                if (results.Length < 3)
                                   return (x, (DateTime?)null);

                                return (x, DateTime.ParseExact(results[2], "MMddyyyyhhmmsstt", CultureInfo.InvariantCulture));
                             })
                      .OrderBy(x => x.Date == null)
                      .ThenBy(x => x.Date)
                      .ThenBy(x => x.Value)
                      .ToList();

用法

foreach (var item in orderedList)
   Console.WriteLine(item.Value);

结果

File_1710485_08112019111721AM
File_1242161_08112019010101PM
File_1710480
File_1710488
File_1710489

注意:为了清楚起见,我使用了显式命名的元组,您可能会使它看起来更简洁

注2:至于高性能,还有其他解决方案......但是,除非您要解码数百万个文件,否则您会发现获取文件名的调用超过了例程的成本


推荐阅读