为啥 .Net 字典看起来像是排序的? [复制]
Posted
技术标签:
【中文标题】为啥 .Net 字典看起来像是排序的? [复制]【英文标题】:Why does the .Net Dictionary look like it is sorted? [duplicate]为什么 .Net 字典看起来像是排序的? [复制] 【发布时间】:2012-04-07 01:20:42 【问题描述】:我正在查看我的同事签入的一些代码,它看起来像这样:
return list.OrderBy(item => item.Order).ToDictionary(item => item.Id);
我立即告诉我的同事他的代码是错误的,因为Dictionary
是一个哈希表,一个未排序的集合。我说,他应该使用保持顺序的集合,或者稍后在他使用foreach
从字典中读取项目时对项目进行排序。
但他回答“不,不,我的代码是正确的!看:现在我已经添加了OrderBy
,项目以正确的顺序显示。”
事实证明,在测试用例上,他是对的。我尝试了一些其他数据,但它仍然是完美排序的!
我告诉他他不应该依赖这种行为,但他不同意,我无法解释原因。此外,我对为什么订单似乎经常被保留很感兴趣。
所以我的问题是......为什么Dictionary
,一个根本上未排序的集合,看起来很像它是排序的?
【问题讨论】:
Dictionary 不保证集合是无序的。它不会故意使用 Random。是的,代码错了。 是的,贾斯汀,这是重复的。您链接的问题的答案是我想要的。你怎么能在这么多关于字典的问题中这么快找到重复的?我搜索并找不到它。谢谢! 我不知道(这就是我将其作为评论发布的原因)但我想这与 SQL 中的相同:SELECT
返回的行以未指定的顺序返回,除非包括ORDER BY
子句。通常,特别是在小型数据集中,行以它们插入的相同顺序返回,这让很多人感到困惑。 (我总是告诉人们,如果他们完全关心结果的顺序,请添加 ORDER BY
。没有它它可能工作,但它也可能会严重损坏。)
@EldritchConundrum -- 这是.net dictionary order
在 Google 上的第一个结果。我发现 Google 有时比内置搜索效果更好。
【参考方案1】:
在遍历字典时,您会在 the order they were inserted to the dictionary 中获得其中的项目。
在示例中,对列表进行排序,然后将每个项目依次添加到字典中。
最终结果是字典中的项目按照列表的排序顺序。
但是,Dictionary
的当前实现恰好是这种情况 - 不能保证它会保持这种状态。
如果您需要将Dictionary
中的项目按特定顺序排列,您应该使用SortedDictionary
。
【讨论】:
您能否更好地解释一下为什么要对它们进行排序。我会说他们是由他们的哈希“排序”的,即属性“Id” @LuisFilipe - 我不关注。该列表已排序(list.OrderBy(item => item.Order)
然后转换为Dictionary
。转换通过将每个项目添加到字典来进行。字典中的项目是“有序”的,因为它们是按插入顺序排列的。因为它们是 按顺序插入,字典按顺序。
这是否由规范/合同保证,或者它是如何编写特定实现的工件?如果它是有保证的行为,引用将是有用的。
@MichaelKjörling - 无法保证,这只是当前版本的Dictionary
的实现方式。
Luis,实际上键是按哈希相关的顺序存储的,但值不是,字典枚举器使用值存储。【参考方案2】:
它是排序的,因为Dictionary
是如何实现的(在你的情况下,项目是按顺序添加的)。但这是实现细节。
告诉你的同事存在一个SortedDictionary 类,这应该让他相信我们不能用简单的Dictionary
来依赖项目订单;)
【讨论】:
这是一个实现细节,当然,但我认为它不会改变。也许可以说只有 Add() 的字典确实保留了顺序。 @EldritchConundrum 真的,你不应该这样假设。目前是这样,但在未来的版本中可能不会。想想框架的其他实现(例如 Mono),不能保证它们以相同的方式实现 Dictionary。 是的。更重要的是,现在我知道如何构建我同事的代码将失败的测试用例;)我只需要在 foreach 之前删除和添加。以上是关于为啥 .Net 字典看起来像是排序的? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Python 在格式化时将此字符串解释为字典? [复制]
为啥 .NET 中没有 SortedList<T>? [关闭]