2011-10-08 61 views
33

将整数用作Ruby散列中的键是否合适?使用整数作为散列键

文档中的每个示例都显示一个字符串或符号被用作键,但从不是整数。

在内部,将整数以某种方式转换为字符串?我看到了有关这个问题的一些矛盾的信息。

换句话说,使用整数键来散列有什么重大的缺点?

+2

你试过了吗?在你的控制台上,你可以输入IRB并获得一个ruby控制台..对于尝试这种类型的东西非常有用......在主题上,你应该能够使用整数就好。 – Deleteman

+1

[“除了索引是通过任意对象类型的任意键完成的”](http://www.ruby-doc.org/core/Hash.html)。整数是Ruby中的对象,Hashes也是如此,所以你可以使用Hashes作为键。 –

回答

42

当然你可以使用整数作为键...

h = {1 => 'one', 2 => 'two', 3 => 'three'} 

(1..3).each do |i| 
    puts h[i] 
end 

=>

one 
two 
there 

IRB是你的朋友!试试吧..


事实上,你可以使用任何Ruby对象的键(或价值)。 我们通常不会考虑像这样使用Hashes,但它可能非常有用。

+0

有一件事我发现有关数字键的哈希文字有趣的是你不能使用语法{1:'one',2:'two'}。我猜这个语法假定每个键都是一个符号,而整数不是。 – BlueMonkMN

+0

是的,x:只适用于符号 – Tilo

9

使用对象作为散列键的唯一要求是它必须以散列值响应消息散列,并且给定键的散列值不得更改。举例来说,如果你把这个:

1.hash() 

你可以看到,1号确实响应散列消息

+0

我认为它曾经是1.8。但我不确定它在1.9中仍然如此。我的意思是,在1.9中你可以免费得到一个散列。 – Candide

+0

对,我不是故意说你必须明确地调用你想用作键的对象的hash() - 重要的是对象实现了hash()方法(或者'响应哈希消息',用OO的说法) –

+5

它也必须响应'eql?'。 –

3

目前已经回答了关于is it possible?

解释,为什么没有整数作为哈希键的例子。

散列键具有(大多数情况下)的含义。它可能是属性名称及其值(例如:color => 'red' ...)。

当你有一个整数作为一个键,你的语义可能是'第一,第二...'(1)。但是,你不使用散列,而是一个数组来存储你的值。

(1)反例可能是数据库中的外键。

26

其他望着这里的答案会觉得很有趣知道发生异常,当你在一个Ruby hash{symbol: value}

hash = {1: 'one'} # will not work 
hash = {1 => 'one'} # will work 

要求的解释使用整数作为符号键:

最简单的答案为什么第一个例子失败的原因可能是to_sym不是针对Fixnum整数实施的方法。

为了更深入地解释这是为什么,使用符号的一个主要好处是两个符号实际上是“同一个对象”。或者至少他们共享相同的对象ID。

:foo.object_id == :foo.object_id 
=> true 

相同的字符串不共享相同的对象,因此不共享相同的对象ID。

"foo".object_id == "foo".object_id 
=> false 

像符号一样,相同的Fixnum整数将具有相同的对象ID。因此你并不需要将它们转换成符号。

one = 1 
=> 1 
uno = 1 
=> 1 
one.object_id 
=> 3 
one.object_id == uno.object_id 
=> true