首页 > 解决方案 > 在 ruby​​ 中,为什么 Set 是无序的,而 Hash 是按插入顺序保证的?

问题描述

ruby 2.5.1 中的哈希

哈希按照插入相应键的顺序枚举它们的值。

在 ruby​​ 2.5.1 中设置

Set 实现了一组无重复的无序值。

我认为 set 在 ruby​​ 中实现为哈希。那么为什么 Set 是无序的,而 Hash 是按插入顺序保证的呢?

更新:

我知道数学上的集合应该是无序的。

出现了一个重要的问题,即使Set该类实际上是按插入顺序排列的,但它没有记录在案。我认为应该更新文档。

即使在Set#add源代码中,我们也可以看到它实际上是在使用Hash

# File set.rb, line 348

def add(o)
  @hash[o] = true
  self
end

注意:我并不是要引发讨论,但认为在某处记录这一事实很重要。如果不在官方文档中,至少在堆栈溢出时。

标签: ruby

解决方案


Set 在语义上是无序的;一个兼容的实现可以将它构建在一个实际无序的核心之上。(例如,我不确定 JRuby 做了什么,尽管我想他们可能使用与 CRuby 相同的基于哈希的实现。)

正如您所注意到的,Set 实际上是使用 Hash 实现的——这意味着它实际上会保留插入顺序……规范并不能保证它。

如果您问为什么要这样定义,那么文档很可能早于保证哈希排序并且从未被修改过(同样可能这是一个有意识的选择)。它最近在https://bugs.ruby-lang.org/issues/14069中提出,但到目前为止还没有看到任何讨论。


推荐阅读