【问题标题】:"Hashes enumerate their values in the order that the corresponding keys were inserted."“哈希按照插入相应键的顺序枚举它们的值。”
【发布时间】:2017-03-08 10:34:33
【问题描述】:

来自http://ruby-doc.org/core-2.4.0/Hash.html#method-i-each 的 ruby​​ 文档:

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

通常,我希望以随机顺序枚举哈希(以任意语言)。

ruby 如何跟踪插入顺序?除了哈希桶之外,它是否在键之间保留了一个链接列表?我想这很简单,但我真的很惊讶(以一种好的方式)他们一开始就这样做了。

【问题讨论】:

  • 这是一个实现细节,我猜这取决于 Ruby 实现。
  • @sawa 不,不是,这就是为什么文档没有说这是一个实现细节。任何 1.9 后的 ruby​​ 都会有这些,这是类合同的变化。
  • 我并不是说实现细节中的有序散列。我是说Ruby“按顺序管理”的方式(你问的)是一个实现细节。

标签: ruby hash enumeration


【解决方案1】:

是的,它保存了一个链表。这可以在不损害典型哈希表的典型 O(1) 摊销最坏情况步复杂度保证的情况下完成,因为所有使链接列表变得昂贵的操作(例如删除元素)都与需要按顺序遍历列表有关find 一个元素,但在这种特殊情况下,“finding”部分可以通过使用哈希表查找来短路。

如果您对 Ruby 实现的内部结构感兴趣,我建议您阅读 Rubinius 源代码;它比 YARV 更简洁、更易于阅读,此外,它是用 Ruby 编写的,你可能已经熟记于心了。 Rubinius 的Hash 类在core/hash.rb 中实现。请注意,当前版本的 Rubinius 使用Hash Array Mapped Trie (HAMT),这与 YARV 使用的简单传统哈希表有很大不同,但这与附加链表的使用无关。如果你真的想,你可以看看older version,它仍然有传统的哈希表。

【讨论】:

    【解决方案2】:

    这个forum 有您正在寻找的确切答案,并且由 Matz 本人回答。

    谁能解释一下为什么要添加这个功能?

    在某些情况下很有用,尤其是关键字参数。

    这不会减慢对 Hash 的操作吗?

    没有。哈希引用操作不触及订单信息,仅 用于迭代。内存消耗增加了一点。

    【讨论】:

    • “确切答案”应该是“如何?”,而不是“为什么?”。
    猜你喜欢
    • 2019-03-19
    • 2012-08-14
    • 2017-08-16
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 2014-11-22
    相关资源
    最近更新 更多