Ruby 使用hashmap测试顺序

Ruby 使用hashmap测试顺序,ruby,hash,hashmap,Ruby,Hash,Hashmap,我是一个ruby初学者,读到散列没有顺序。我试着玩弄这个概念,但发现我仍然可以订购这样的东西: 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初学者,读到散列没有顺序。我试着玩弄这个概念,但发现我仍然可以订购这样的东西:

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
类用常规术语表示“Hash映射”或“键值字典”。这些结构允许快速随机访问单个元素,但元素本身没有内在的顺序

在内部,Ruby的
Hash
使用
Hash
方法将元素组织到内存中的各个位置,每个对象必须提供该方法才能用作键。Ruby的
散列
非常灵活,即使不是可笑的灵活,因为一个对象,任何一个对象,都可以用作键,并且它完全按照原样保存。与JavaScript不同,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
当您在
散列
上调用
排序
时,实际上会将其转换为一个键/值对数组,然后对其中的每一个进行排序:

b.sort
# => [[:x, "1"], [:y, "2"]]
如果需要,您可以将其转换回
散列

b.sort.to_h
# => {:x=>"1", :y=>"2"}
所以现在它是“有序”的。但在实践中,这并不重要,因为您将根据需要单独访问密钥
b[:x]
不管
:x
键在哪里,它总是返回正确的值

关于Ruby,需要注意以下几点:

  • 不要使用
    Hash.new
    ,而只需使用
    {}
    来表示一个空的Hash结构
  • 不要使用大写字母作为变量,它们在Ruby中具有重要意义<代码>旅行计划是一个常量,而不是变量,因为它以大写字母开头。这些是为
    ClassName
    CONSTANT\u NAME
    类型用法保留的。这应该是
    旅行计划
首先,从今天起,“灰烬没有秩序”的说法是错误的。对于非常古老和过时的Ruby版本来说,这是事实。您似乎选择了过时的信息,从今天起这些信息都是不可靠的

第二,您提供的代码:

puts Travel_Plans.sort
与显示散列
旅行计划
具有(即保留)顺序的点无关。要检查订单是否保留,您只需执行以下操作:

p Travel_Plans

这将始终导致按顺序显示键
4
1
2
5
3
,这与您将键值分配给散列的顺序相匹配,因此确实表明散列保留了顺序。

回答得好!但是为什么
{}
Hash.new
更受欢迎呢?它不那么冗长,这通常是Ruby代码的方向,并且映射到其他语言,如JavaScript,在这些语言中,符号是相同的。您可以在需要自定义行为的特殊情况下使用
Hash.new
,如
Hash.new(0)
Hash.new{h,k |…}
。非常好的解释。诡辩:也许是“平等”而不是“同等”。当Hash <代码> h <代码>没有密钥<代码> k>代码>时,请考虑<代码> > [k>代码],<代码>获取< <代码>和默认值(只要你已经走了这么远)。散列的内容是相等的,但对象本身不是<代码>a.equal?b#=>false当转换为数组时,它们也不会被视为相等
a.to_a==b.to_a#=>false
在我看来“等效”更合适,但在散列上下文中“相等”也适用。我必须同意等效是正确的术语,在这里它们不一定相等,但它们是等效的,因为可以在孤立上下文中进行比较,以表示相等。特别是考虑到这个问题是关于顺序的,它们的顺序当然不等于前面提到的,但它们是等价的,因为它们的键=>值关联在顺序上是相同的。也许你可以说它们是
eql?
:)