键值对有序列表?

9
在.NET中是否有一个集合可以存储KeyValuePair<string, string>并保持插入顺序?OrderedDictionary看起来很有前途,但似乎相当缺乏。现在我正在研究IOrderedEnumerable>,但是除了ISortedDictionary之外,我似乎找不到任何实现,但那不是我想要的。不需要进行排序,只需重要的是插入的顺序。
更新:我不喜欢OrderedDictionary的原因是它不是泛型的。

OrderedDictionary没有对值进行排序,可以通过索引访问元素。到底缺少什么? - Adrian Fâciu
OrderedDictionary 是你正在寻找的内容,但不幸的是它不是通用的。除此之外,还有什么其他的东西是你所需要的吗?如果你能澄清你所需要的内容(以及为什么内置类不能满足你的需求),你将会得到更好的答案。 - LBushkin
如若可能,我希望尽量避免所有的类型转换。 - Boris Callens
5个回答

10

只需使用 List<KeyValuePair<T,T>>。它们按插入顺序存储。每次添加时,最新的项将添加到列表末尾。

因此,

var list = new List<KeyValuePair<String,String>>();

list.Add(new KeyValuePair<String,String>("",""));

如果您想按顺序将它们取出,只需使用以下代码:
list.ForEach(x=>...);

或者
foreach(var item in list){
...}

列表是否保证顺序不变? - Boris Callens
1
是的,它必须这样做,因为您可以像访问数组List[0]等一样直接访问元素。 - kemiller2002
旧帖但是对于其他人来说,只要您不明确排序,List<T>会保持顺序。此外,您的删除操作将更改索引...尽管从已删除的位置向下移动。 - Ken

10
虽然我来晚了,但.NET Framework 4.5为您提供了新的类。请查看SortedList<TKey, TValue>SortedDictionary<TKey, TValue>。如果您想知道应该使用哪个,请参考MSDN,它提供了一些选择一个而不是另一个的好理由。
SortedLis泛型类是具有O(log n)检索的键/值对数组,其中n是字典中元素的数量。在这方面,它类似于SortedDictionary泛型类。两个类具有相似的对象模型,并且都具有O(log n)检索。两个类的区别在于内存使用和插入/删除速度:
- SortedList<TKey, TValue>比SortedDictionary<TKey, TValue>使用更少的内存。 - 对于未排序的数据,SortedDictionary<TKey, TValue>具有更快的插入和删除操作,为O(log n),而SortedList<TKey, TValue>为O(n)。 - 如果列表一次性从排序数据中填充,则SortedList<TKey, TValue>比SortedDictionary<TKey, TValue>更快。
SortedDictionary<TKey, TValue>和SortedList<TKey, TValue>类之间的另一个区别是,SortedList<TKey, TValue>通过Keys和Values属性返回的集合支持高效的索引检索键和值。当访问这些属性时,无需重新生成列表,因为列表只是键和值的内部数组的包装器。
两个链接都有类似的备注部分(引用来自此处)。它们还提供了更多关于两个类的信息。如果您有兴趣使用其中之一,我建议阅读两个部分。

1
SortedList不维护插入顺序,而这正是OP要求的(也是我所需要的)。 - Brad Patton
键值对列表相比于有序列表/有序字典是最好的方式。它按照插入顺序维护索引并支持通用类型。 - Kumar Shishir

8

OrderedDictionary是一种同时支持按键和插入顺序访问项的数据结构,它实际上就是哈希表和列表的组合。它提供了一种通过插入索引或关键字来访问其中项的方法。这是.NET中唯一具备这种特性的集合。不过遗憾的是,它不是泛型的。

如果仅仅因为不是泛型的而OrderedDictionary不能满足您的需求,那么可以使用此处提供的泛型版本。如果还有其他原因导致它无法满足您的需求,请更新您的帖子,我们可以寻找更好的选择。

虽然您确实可以创建自己的List<KeyValuePair<string,string>>,但您将失去有效地按键搜索的选项。现在,您当然可以自己实现一个组合了列表和字典的有序字典,但我已经在链接的帖子中提供了这样的实现。


这很好地总结了我的选择。既然我不需要键查找,我就选择IList。谢谢。 - Boris Callens
OrderedDictionary.Remove具有O(N)复杂度,因为每次删除一个条目时,所有在它上方的条目都会下移。因此,这个集合并不能在所有方面都复制字典的性能特征。 - Theodor Zoulias

2

一个 Queue<T> 不支持从集合中删除特定元素。你只能出队列头的元素。因此,它不能作为完全功能字典的基础。 - Theodor Zoulias

0
你应该只需要使用一个 List<KeyValuePair<string,string>>。我在 MSDN 文档中并没有找到保证插入顺序的说明,但这是一个相当安全的选择...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接