2011-10-08 64 views
33

¿Es apropiado usar enteros como claves en un hash Ruby?Uso de enteros como claves hash

Cada ejemplo de la documentación muestra una cadena o símbolo que se utiliza como clave, pero nunca un número entero.

Internamente, ¿los enteros de alguna manera se convertirían a cadenas? He visto información conflictiva sobre el tema.

En otras palabras, ¿hay alguna desventaja significativa al usar claves enteras para un hash?

+2

¿Lo has probado? En su consola, puede escribir IRB y obtener una consola de rubí ... bastante útil para probar este tipo de cosas ... Sobre el tema, debería poder usar enteros muy bien. – Deleteman

+1

["excepto que la indexación se realiza mediante claves arbitrarias de cualquier tipo de objeto"] (http://www.ruby-doc.org/core/Hash.html). Los enteros son objetos en Ruby, por lo que son hashes para el caso, por lo que podría usar Hashes como claves. –

Respuesta

42

, por supuesto, puede utilizar las teclas de números enteros como ...

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

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

=>

one 
two 
there 

IRB es su amigo! probarlo ..


De hecho se puede utilizar cualquier rubí objeto como la clave (o el valor). Normalmente no pensamos en usar hashes como este, pero podría ser bastante útil.

+0

Una cosa que me resulta interesante sobre los literales hash con claves numéricas es que no puede usar la sintaxis {1: 'uno', 2: 'dos'}. Supongo que esa sintaxis supone que cada clave es un símbolo, cuyos enteros no lo son. – BlueMonkMN

+0

sí, x: solo funciona para los símbolos – Tilo

9

El único requisito para utilizar un objeto como clave hash es que debe responder al hash del mensaje con un valor hash, y el valor hash para una clave determinada no debe cambiar. Por ejemplo, si se llama a esto:

1.hash() 

Se puede ver que el número 1 de hecho responde al mensaje de hash

+0

Creo que solía ser así en 1.8. Pero no estoy tan seguro de que todavía sea cierto en 1.9. Quiero decir, en 1.9 obtienes un hash gratis. – Candide

+0

Correcto, no quise decir que debe llamar explícitamente hash() al objeto que desea usar como clave; lo que importa es que el objeto implemente el método hash() (o 'responda al mensaje hash ', en el lenguaje de OO) –

+5

También tiene que responder a 'eql?'. –

3

Ya hay respuestas sobre el is it possible?.

Una explicación, por qué no hay ejemplos con enteros como Hash-keys.

Las teclas hash tienen (la mayoría de las veces) un significado. Puede ser un nombre de atributo y su valor (por ejemplo, :color => 'red' ...).

Cuando tiene un entero como clave, su semántica puede ser 'primero, segundo ...' (1). Pero luego no usa un hash, sino una matriz para almacenar sus valores.

(1) Un contraejemplo puede ser una clave externa en una base de datos.

26

Otros buscan en las respuestas aquí que le resulte interesante saber que una excepción ocurre cuando se utiliza enteros como teclas de símbolos en un Ruby hash{symbol: value}

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

explicación solicitada:

La respuesta más simple por qué el primer ejemplo falla es probable que to_sym no sea un método implementado para enteros Fixnum.

Para profundizar en la explicación de por qué, uno de los principales beneficios del uso de símbolos es que dos símbolos son "el mismo objeto". O al menos comparten los mismos ID de objeto.

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

Las cadenas que son iguales no comparten los mismos objetos y, por lo tanto, no comparten los mismos ID de objeto.

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

Al igual que los símbolos, números enteros Fixnum que son los mismos tendrán los mismos identificadores de los objetos. Por lo tanto, no es necesario convertirlos en símbolos.

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