【问题标题】:The order of elements in Dictionary字典中元素的顺序
【发布时间】:2011-04-29 19:08:16
【问题描述】:

我的问题是关于枚举字典元素

// Dictionary definition
private Dictionary<string, string> _Dictionary = new Dictionary<string, string>();

// add values using add

_Dictionary.Add("orange", "1");
_Dictionary.Add("apple", "4");
_Dictionary.Add("cucumber", "6");

// add values using []

_Dictionary["banana"] = 7;
_Dictionary["pineapple"] = 7;

// Now lets see how elements are returned by IEnumerator
foreach (KeyValuePair<string, string> kvp in _Dictionary)
{
  Trace.Write(String.Format("{0}={1}", kvp.Key, kvp.Value));
}

枚举元素的顺序是什么?我可以强制按字母顺序排列吗?

【问题讨论】:

标签: c# .net dictionary ienumerable


【解决方案1】:

字典中元素的顺序是不确定的。没有为哈希表定义顺序的概念。因此,不要依赖于以与元素添加到字典中相同的顺序进行枚举。这不能保证。

引用from the doc

出于枚举的目的,字典中的每个项目都被视为一个KeyValuePair&lt;TKey, TValue&gt; 结构,表示一个值及其键。返回项目的顺序未定义。

【讨论】:

【解决方案2】:

您可以随时使用SortedDictionary。请注意,字典默认按 Key 排序,除非指定了比较器。

我对使用 OrderedDictionary 来满足您的需求持怀疑态度,因为文档说:

OrderedDictionary 的元素不按键排序,不像 SortedDictionary 类的元素。

【讨论】:

  • 重要的是要注意SortedDictionary&lt;K,V&gt; 是作为二叉搜索树实现的,与基于哈希表的Dictionary&lt;K,V&gt; 相比,它的操作时间和空间复杂度不同。如果用户需要O(1) 插入/删除哈希表结构并且还想以键顺序迭代元素,那么他们应该使用dict.Keys.OrderBy( k =&gt; k ).Select( k =&gt; dict[k] ) 代替(以O(n) 空间和O( n log n ) 时间为代价)用于@987654331 @(这将需要在内部列表中缓冲整个键集合)。
【解决方案3】:

如果您希望元素排序,请使用SortedDictionary。普通的 hastable/dictionary 仅在某种意义上的存储布局中排序。

【讨论】:

  • OrderedDictionary 在大多数情况下是错误的。它既不是按键或值排序,而是按内部索引排序。 SortedDictionary 是以用户可以操作的方式排序的字典(默认键)
  • 问题是询问按字母顺序排序(假设提问者正在谈论密钥)。如果我正确理解文档,有序字典将按照插入的顺序吐出元素,即不是按字母顺序,而是使用内部索引。 SortedDictionary 可能最适合用户的问题。
【解决方案4】:

这些项目将按照它们碰巧物理存储在字典中的顺序返回,这取决于哈希码和添加项目的顺序。因此,顺序看起来是随机的,并且随着实现的变化,您永远不应该依赖于保持不变的顺序。

您可以在枚举项目时对其进行排序:

foreach (KeyValuePair<string, string> kvp in _Dictionary.OrderBy(k => k.Value)) {
  ...
}

在框架 2.0 中,您首先必须将项目放入列表中才能对其进行排序:

List<KeyValuePair<string, string>> items = new List<KeyValuePair<string, string>>(_Dictionary);
items.Sort(delegate(KeyValuePair<string, string> x, KeyValuePair<string, string> y) { return x.Value.CompareTo(y.Value); });
foreach (KeyValuePair<string,string> kvp in items) {
  ...
}

【讨论】:

    【解决方案5】:

    对于有序字典:

     var _OrderedDictionary = new System.Collections.Specialized.OrderedDictionary();
    
    _OrderedDictionary.Add("testKey1", "testValue1");
    _OrderedDictionary.Add("testKey2", "testValue2");
    _OrderedDictionary.Add("testKey3", "testValue3");
    
    var k = _OrderedDictionary.Keys.GetEnumerator();
    var v = _OrderedDictionary.Values.GetEnumerator();
    
    while (k.MoveNext() && v.MoveNext()) {
        var key = k.Current; var value = v.Current;
    }
    

    项目按添加顺序返回。

    【讨论】:

      【解决方案6】:

      关联数组(又名哈希表)是无序的,这意味着可以以任何可以想象的方式对元素进行排序。

      但是,您可以获取数组键(仅键),按字母顺序(通过排序函数)排序,然后进行处理。

      我不会给你一个 C# 示例,因为我不懂语言,但这应该足以让你自己继续。

      【讨论】:

        猜你喜欢
        • 2011-08-13
        • 2020-06-30
        • 1970-01-01
        • 1970-01-01
        • 2017-09-18
        • 1970-01-01
        • 2018-08-02
        • 2014-02-07
        • 2023-04-10
        相关资源
        最近更新 更多