【问题标题】:Why the limitations on Dictionary sorting in C#?为什么在 C# 中字典排序有限制?
【发布时间】:2014-05-21 09:30:49
【问题描述】:

最近从另一个非常喜欢字典的开发人员那里接手了一个应用程序,并以不同程度的适当性在所有地方使用它们。

我收到了很多更改请求,要求对应用程序中的各种内容进行排序,这显然是个问题,因为您无法对字典进行排序。我知道:我以前被它咬过,这是我避免使用字典的原因之一,除非真的没有其他解决方案。

我没想到的是,SortedDictionary 的局限性在于,开箱即用,它只按 Key 排序,并且只在一个方向上排序。

我对这个问题的解决方案不是特别感兴趣:SO 已经充满了它们。我只是好奇是否有很好的技术或架构原因来为什么在 C# 中仍然没有对字典进行排序的功能,以及为什么 SortedDictionary 上的默认行为如此有限?

编辑:需要一个具体的例子,所以这是我正在处理的一个例子。请记住,我不是在这里寻找解决方案(我创建了一个 IComparer 来在现实生活中完成这项工作)——这只是为了说明。

在本例中,它是一个 WPF 应用程序,字典用作将键/值对存储在一起的一种方式,以便用户界面可以使用 DisplayMemberPath="Key" SelectedValuePath="Value" 创建一个组合框。

Dictionary<string, int> JobsDict = rep.Jobs_Get()
                                     .Where(x => x.MemberID == SelectedMemberID)
                                     .ToDictionary(x => x.Description, x => x.JobID);

//Jobs is a property of type SortedDictionary<string, int> that the UI binds to
Jobs = new SortedDictionary<string, int>(JobsDict);

//what I'd like to do at this point is ...
Jobs.OrderByDescending(x => x.Value);
//so that the user sees the most recent values at the top of the list

【问题讨论】:

  • “只在一个方向排序”是什么意思?您可以指定 IComparer&lt;TKey&gt; 并因此按您喜欢的方式排序 - 不过仍然基于密钥。
  • 因为字典使用不保证任何项目顺序的哈希表,而排序字典使用某种平衡树(可能是 RB-tree?),它使用比较器作为键。这就是这些数据结构的工作原理......
  • @JonSkeet 是的,我明白了。但是只调用 LINQ .OrderBy 或 .OrderByDescending,或者在某些情况下只调用 .Reverse 会容易得多。我只是好奇为什么这些速记选项不可用。
  • @MattThrower 对每个调用进行排序不同于按顺序存储数据
  • 我建议您使用 具体 示例更新问题,说明您希望提供哪些内容,同时记住 Marc 关于存储与“随用随用”排序的评论。

标签: c# sorting dictionary


【解决方案1】:

一般来说,字典类型被实现为哈希表以提高效率。因为决定项目进入哪个桶的是哈希函数,而不是添加到集合中的顺序,所以我们甚至无法跟踪顺序。这样做会损害字典的有效性,此时你还不如回到列表/数组。

【讨论】:

    【解决方案2】:

    只是为了补充上面的答案:

    如果您确实想为一个列表设置多个排序顺序而不必多次使用,您可以通过为每个排序顺序创建一个整数索引数组来轻松地做到这一点。

    然后您按照您想要原始项目列表的顺序对索引数组进行排序(并且您根本不对原始列表进行排序)。

    只有在不更改源集合中的数据的情况下多次使用按排序顺序排列的项目时,您才会这样做。否则,您最终会采取太多措施,您不妨按需使用.OrderBy

    这里有一些示例代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace ConsoleApp1
    {
        sealed class Item
        {
            public int Number1;
            public int Number2;
    
            public override string ToString()
            {
                return string.Format("Number1 = {0}, Number2 = {1}", Number1, Number2);
            }
        }
    
        class Program
        {
            private void run()
            {
                var data = createTestData();
    
                var sort1 = Enumerable.Range(0, data.Count).ToArray(); // Indices to use to sort list by Number1.
                var sort2 = Enumerable.Range(0, data.Count).ToArray(); // Indices to use to sort list by Number1.
    
                Array.Sort(sort1, (a, b) => (data[a].Number1 - data[b].Number1));
                Array.Sort(sort2, (a, b) => (data[a].Number2 - data[b].Number2));
    
                Console.WriteLine("Original data:");
    
                foreach (var element in data)
                    Console.WriteLine(element);
    
                Console.WriteLine("\nSorted by Number1:");
    
                foreach (var index in sort1)
                    Console.WriteLine(data[index]);
    
                Console.WriteLine("\nSorted by Number2:");
    
                foreach (var index in sort2)
                    Console.WriteLine(data[index]);
            }
    
            static List<Item> createTestData()
            {
                return new List<Item>
                {
                    new Item {Number1 = 2, Number2 = 3},
                    new Item {Number1 = 1, Number2 = 4},
                    new Item {Number1 = 4, Number2 = 1},
                    new Item {Number1 = 7, Number2 = 6},
                    new Item {Number1 = 5, Number2 = 7},
                    new Item {Number1 = 6, Number2 = 5},
                    new Item {Number1 = 3, Number2 = 2},
                };
            }
    
            static void Main()
            {
                new Program().run();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-17
      • 2015-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多