【问题标题】:In ruby, why is Set unordered while Hash is guaranteed in insertion order?在 ruby​​ 中,为什么 Set 是无序的,而 Hash 是按插入顺序保证的?
【发布时间】:2018-07-01 13:11:06
【问题描述】:

Hash in ruby 2.5.1:

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

Set in ruby 2.5.1:

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

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

更新:

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

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

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

# File set.rb, line 348

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

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

【问题讨论】:

  • 集合是用散列实现的这一事实是无关紧要的。问题仅仅是集合是否应该保留插入顺序。赞成的论点之一是它可以有效地完成,因为集合在幕后使用哈希,但这不是核心问题。至于“为什么”集合不保留插入顺序,您将不得不询问 Ruby 僧侣。显然,他们并没有被说服这样的改变是可取的。由于问题需要意见,因此它并不适合 SO。 (点击SO help“询问”下的第 2 点。)

标签: ruby


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 2011-02-08
    • 2010-11-05
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多