You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按含年月字符串格式的键对Dictionary进行排序?

按时间顺序排序Dictionary的问题解决方法

问题场景

有一个存储年月字符串为Key、整数为Value的Dictionary,需要按实际时间先后顺序排序,但使用默认的SortedDictionary得到的是字典序结果,不符合预期。

原Dictionary定义代码:

Dictionary<string, int> map = new Dictionary<string, int>();
map["Sep 20"] = 10;
map["Oct 20"] = 11;
map["Nov 20"] = 23;
map["Jan 21"] = 15;
map["Feb 20"] = 50;
map["Mar 20"] = 23;

尝试的排序代码:

SortedDictionary<string, int> sortMap = new SortedDictionary<string, int>(map);

foreach (var entry in sortMap)
{
  Console.WriteLine(entry.Key + "\t" + entry.Value);
}

期望输出

Feb 20  50
Mar 20  23
Sep 20  10
Oct 20  11
Nov 20  23
Jan 21  15

实际输出

Feb 20  50
Jan 21  15
Mar 20  23
Nov 20  23
Oct 20  11
Sep 20  10

问题原因

SortedDictionary默认使用字符串字典序排序,而非时间顺序。比如"Jan 21"的首字母J在M之前,所以排在"Mar 20"前面,但实际时间上2020年的所有月份都早于2021年1月,因此默认排序逻辑不满足需求。

解决方案

要实现按时间顺序排序,需要将Key字符串解析为时间对象后比较,以下是两种常用实现方式:

方法1:自定义比较器的SortedDictionary

创建一个实现IComparer<string>的比较器,将年月字符串转换为DateTime后比较时间先后:

using System.Globalization;

public class MonthYearComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        // 按"MMM yy"格式解析字符串为DateTime(英文月份缩写+两位年份)
        if (DateTime.TryParseExact(x, "MMM yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateX) &&
            DateTime.TryParseExact(y, "MMM yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateY))
        {
            return dateX.CompareTo(dateY);
        }
        // 解析失败时回退到字典序
        return string.Compare(x, y);
    }
}

使用该比较器初始化SortedDictionary并添加元素:

SortedDictionary<string, int> sortMap = new SortedDictionary<string, int>(new MonthYearComparer());
foreach (var entry in map)
{
    sortMap.Add(entry.Key, entry.Value);
}

// 遍历输出
foreach (var entry in sortMap)
{
    Console.WriteLine($"{entry.Key}\t{entry.Value}");
}

方法2:Linq直接排序生成集合

如果不需要长期维护有序集合,可直接用Linq对原Dictionary的元素排序,生成新的有序集合:

using System.Linq;
using System.Globalization;

var sortedEntries = map.OrderBy(entry => 
    DateTime.ParseExact(entry.Key, "MMM yy", CultureInfo.InvariantCulture));

foreach (var entry in sortedEntries)
{
    Console.WriteLine($"{entry.Key}\t{entry.Value}");
}

注意事项

  • 确保年月字符串格式统一,若你的格式不是"MMM yy",需调整ParseExact中的格式字符串。
  • 使用CultureInfo.InvariantCulture可避免因系统区域设置不同导致的月份解析失败(比如非英文系统的月份缩写差异)。

内容的提问来源于stack exchange,提问作者Sawan Meshram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 04:15:30