字典中元素的顺序


107

我的问题是关于枚举Dictionary元素

// 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));
}

元素将以什么顺序列出?我可以强制顺序为字母顺序吗?


Answers:



28

如果您希望元素排序,请使用OrderedDictionary。普通的hastable / dictionary仅在某种程度上对存储布局进行排序。


10
在大多数情况下,OrderedDictionary是错误的。它既不是通过键或值排序的,也不是通过内部索引排序的。SortedDictionary是一种以用户可以操纵的方式排序的键(默认键)
Offler

2
问题是询问按字母顺序排序(假设提问者正在谈论密钥)。如果我正确理解文档,那么有序词典将按插入元素的顺序吐出元素,即不是按字母顺序,而是使用内部索引。SortedDictionary可能最适合用户的问题。
mattpm '18

28

您可以随时使用SortedDictionary它。请注意,默认情况下,除非已指定比较器,否则字典将按Key排序。

我对OrderedDictionary您想要的东西的使用表示怀疑,因为文档中说:

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


重要的是要注意,它SortedDictionary<K,V>是作为二进制搜索树实现的,与基于散列表的相比,它的操作在时间和空间上具有不同的复杂度Dictionary<K,V>。如果用户需要O(1)插入/删除哈希表结构,并且还想按键顺序遍历元素,那么他们应该dict.Keys.OrderBy( k => k ).Select( k => dict[k] )(以O(n)占用空间和O( n log n )时间为代价)代替(OrderBy()需要将整个键集合缓冲在内部列表中) )。

12

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

您可以在枚举项目时订购它们:

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

在Framework 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) {
  ...
}

11

对于OrderedDictionary:

 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;
}

按添加顺序返回项目。


5

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

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

我不能给您C#示例,因为我不懂该语言,但这足以让您继续前进。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.