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

C#如何实现按Person.Name排序的字典存储人员及其订单数据

C# 实现按姓名排序的人员订单存储方案

核心解决思路

你的需求可通过两种方案实现,均满足「一次排序、永久使用」的要求,无需每次展示前重新排序:


方案一:自定义排序键的 SortedDictionary 实现

适合同时需要按姓名排序遍历和按键快速查找的场景,通过自定义比较规则控制排序逻辑:

  1. 自定义包含姓名、ID的键结构,实现IComparable<T>接口,优先按姓名排序,姓名相同则按ID排序保证键唯一
  2. 直接使用SortedDictionary存储,插入时自动完成排序,后续遍历顺序固定

代码实现

// 自定义人员排序键,内置排序规则
public struct PersonSortKey : IComparable<PersonSortKey>
{
    public string Name { get; }
    public string Id { get; }

    public PersonSortKey(string name, string id)
    {
        Name = name;
        Id = id;
    }

    public int CompareTo(PersonSortKey other)
    {
        // 优先按姓名升序
        int nameCompare = string.Compare(Name, other.Name, StringComparison.Ordinal);
        if (nameCompare != 0) return nameCompare;
        // 姓名相同按ID排序,保证键全局唯一
        return string.Compare(Id, other.Id, StringComparison.Ordinal);
    }
}

// 初始化字典
var lastOrders = new SortedDictionary<PersonSortKey, Queue<Order>>();

// 插入示例
lastOrders.Add(new PersonSortKey("Anne", "n4"), new Queue<Order>(new[] { new Order("Salami"), new Order("Ananas") }));
lastOrders.Add(new PersonSortKey("Ben", "n2"), new Queue<Order>(new[] { new Order("Apple") }));
lastOrders.Add(new PersonSortKey("Ben", "n3"), new Queue<Order>(new[] { new Order("Banana") }));
lastOrders.Add(new PersonSortKey("Cesar", "n1"), new Queue<Order>(new[] { new Order("Banana"), new Order("Cheese") }));

遍历直接foreach即可输出你需要的顺序。


方案二:双索引预排序实现(更适合你的场景)

你的场景中人员数据静态,该方案性能更优:

  1. 用普通Dictionary按ID存储订单队列,保证更新订单时O(1)查找效率
  2. 初始化时一次性生成按姓名升序的展示列表,列表中存储队列的引用,后续订单更新会自动同步到列表中,无需重新排序

代码实现

// 按ID索引的订单字典,用于快速更新订单
private readonly Dictionary<string, Queue<Order>> _orderById = new Dictionary<string, Queue<Order>>();
// 预排序的展示列表,初始化后固定顺序
private List<(string PersonName, Queue<Order> Orders)> _sortedDisplayList;

// 应用启动时调用一次初始化即可
public void InitStaticData(IEnumerable<Person> allPersons)
{
    // 初始化ID索引
    foreach (var person in allPersons)
    {
        _orderById.Add(person.Id, new Queue<Order>());
    }
    // 一次性完成排序,后续无需修改
    _sortedDisplayList = allPersons
        .OrderBy(p => p.Name)
        .Select(p => (p.Name, _orderById[p.Id]))
        .ToList();
}

// 更新订单方法,O(1)效率
public void AddNewOrder(string personId, Order order)
{
    if (_orderById.TryGetValue(personId, out var queue))
    {
        queue.Enqueue(order);
    }
}

// 展示时直接遍历预排序列表
public void PrintAllOrders()
{
    foreach (var item in _sortedDisplayList)
    {
        var orderNames = string.Join(", ", item.Orders.Select(o => o.Name));
        Console.WriteLine($"- {item.PersonName}: {orderNames}");
    }
}

之前方案问题说明

你之前使用KeyValuePair作为复合键时排序不符合预期,是因为KeyValuePair的默认比较逻辑优先比较第一个字段,你把ID放在了第一位,所以会按ID排序,调整字段顺序后配合自定义比较器也可以实现需求,但自定义结构体的可读性更强。

内容的提问来源于stack exchange,提问作者Louise Delgado

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:36:05