【问题标题】:Testing order using a hashmap使用哈希图测试订单
【发布时间】:2019-03-22 13:18:50
【问题描述】:

我是一名 ruby​​ 初学者,并且读到 Hash 没有顺序。我尝试使用这个概念,但发现我仍然可以这样订购:

Travel_Plans = Hash.new
Travel_Plans[4] = "Colorado Springs"
Travel_Plans[1] = "Santa Fe"
Travel_Plans[2] = "Raton"
Travel_Plans[5] = "Denver"
Travel_Plans[3] = "Pueblo"

puts Travel_Plans.sort

有人可以解释“哈希没有顺序”是什么意思吗?

如果你能提供一个简单的例子那就太好了。

【问题讨论】:

    标签: ruby hash hashmap


    【解决方案1】:

    Ruby 的Hash 类在传统术语中表示“哈希映射”或“键值字典”。这些旨在成为允许快速随机访问单个元素的结构,但元素本身没有内在顺序。

    在内部,Ruby 的Hash 使用每个对象必须提供用作键的hash 方法将元素组织到它们在内存中的不同位置。 Ruby 的Hash 非常灵活,即使不是非常灵活,因为一个对象,任何对象,都可以用作键,并且完全按原样保存。与 JavaScript 相比,其中键 必须 是字符串并且只能是字符串。

    这意味着你可以这样做:

    { 1 => 'Number One', '1' => 'String One', :one => 'Symbol One', 1.0 => 'Float One }
    

    其中有四个完全不同的键。

    这与Array 形成对比,其中排序是数组工作方式的重要组成部分。您不希望有一个队列,事情以一种顺序进行,然后以另一种顺序出现。

    现在 Ruby 的 Hash 类过去没有内在顺序,但由于现在流行的需求,它以插入的形式存储顺序。也就是说,插入的第一个项目是“第一个”。通常你不会明确地依赖这种行为,但如果你注意的话,它确实会出现:

    a = { x: '1', y: '2' }
    # => {:x=>"1, :y=>"2"}
    
    b = { }
    b[:y] = '2'
    b[:x] = '1'
    b
    # => {:y=>"2", :x=>"1"}
    

    请注意,b 中的键的顺序是颠倒的,因为它们是以相反的顺序插入的。不过它们仍然是等价的:

    a == b
    # => true
    

    当您在 Hash 上调用 sort 时,实际上最终会将其转换为键/值对数组,然后对其中的每一个进行排序:

    b.sort
    # => [[:x, "1"], [:y, "2"]]
    

    如果需要,您可以将其转换回 Hash

    b.sort.to_h
    # => {:x=>"1", :y=>"2"}
    

    所以现在它已经正确“排序”了。但在实践中,这并不重要,因为您将根据需要单独访问密钥。 b[:x] 不关心 :x 键在哪里,它总是返回正确的值。

    关于 Ruby 的一些注意事项:

    • 不要使用Hash.new,而只是使用{ }来表示一个空的Hash结构。
    • 不要对变量使用大写字母,它们在 Ruby 中具有重要意义。 Travel_Plans 是常量,而不是变量,因为它以大写字母开头。这些是为ClassNameCONSTANT_NAME 类型使用而保留的。这应该是travel_plans

    【讨论】:

    • 很好的答案!但是为什么{ }Hash.new 更受欢迎?
    • 它不那么冗长,这通常是 Ruby 代码所指导的方向,以及映射到其他语言(如 JavaScript),其中该符号是相同的。对于需要自定义行为的特殊情况,例如 Hash.new(0)Hash.new { |h,k| ... },您可以使用 Hash.new
    • 很好的解释。一个小问题:也许是“相等”而不是“等价”。当哈希 h 没有密钥 kfetch 和默认值时,考虑提及 h[k]
    • @CarySwoveland 这取决于您对“平等”的含义。哈希的内容是相等的,但对象本身不是。 a.equal? b #=> false 当转换为数组时,它们也不会被视为相等。 a.to_a == b.to_a #=> false 在我看来“等价”更合适,但在哈希上下文中“等价”也可以。
    • 我必须同意等价是正确的术语,在这里它们不一定相等,但它们是等价的,因为可以在孤立的上下文中以表示相等的方式进行比较。特别是考虑到这个问题是关于排序的,并且它们的顺序肯定不等于所指出的,但它们是等价的,因为它们的键 => 值关联以不知道顺序的方式是相同的。也许你可以说他们是eql? :)
    【解决方案2】:

    首先,“[h]ash 没有顺序”的说法在今天是错误的。对于真正过时和过时的 Ruby 版本,它曾经是正确的。您似乎选择了过时的信息,这在今天是不可靠的。

    二、你提供的代码:

    puts Travel_Plans.sort
    

    与您的观点无关,即哈希 Travel_Plans 具有(即保留)顺序。您应该检查订单是否保留,只需执行以下操作:

    p Travel_Plans
    

    这将始终导致以41253 的顺序显示键,这与您将键值分配给哈希的顺序相匹配,因此确实表明哈希保留了顺序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-01
      相关资源
      最近更新 更多