2011-10-08 17 views
33

È appropriato utilizzare numeri interi come chiavi in ​​un hash di Ruby?Utilizzo di numeri interi come chiavi hash

Ogni esempio dalla documentazione mostra una stringa o un simbolo utilizzato come chiave, ma mai un numero intero.

Internamente, gli interi potrebbero essere convertiti in stringhe in qualche modo? Ho visto alcune informazioni contrastanti sull'argomento.

In altre parole, c'è qualche svantaggio significativo nell'uso delle chiavi integer per un hash?

+2

Hai provato? Sulla tua console, puoi digitare IRB e ottenere una console ruby ​​.. abbastanza utile per provare questo tipo di cose ... In argomento, dovresti essere in grado di usare gli interi bene. – Deleteman

+1

["eccetto che l'indicizzazione avviene tramite chiavi arbitrarie di qualsiasi tipo di oggetto"] (http://www.ruby-doc.org/core/Hash.html). I numeri interi sono oggetti in Ruby, quindi anche gli hash sono così che potresti usare gli hash come chiavi. –

risposta

42

naturalmente è possibile utilizzare gli interi come chiavi ...

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

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

=>

one 
two 
there 

IRB è tuo amico! provarlo ..


In realtà è possibile utilizzare qualsiasi Rubino oggetto come la chiave (o il valore). Di solito non pensiamo di usare Hash come questo, ma potrebbe essere abbastanza utile.

+0

Una cosa che trovo interessante nei confronti degli hash letterali con i tasti numerici è che non è possibile utilizzare la sintassi {1: 'one', 2: 'two'}. Immagino che la sintassi assuma che ogni chiave sia un simbolo, che gli interi non lo sono. – BlueMonkMN

+0

sì, x: funziona solo per i simboli – Tilo

9

L'unico requisito per l'utilizzo di un oggetto come chiave hash è che deve rispondere all'hash del messaggio con un valore hash e che il valore di hash per una determinata chiave non deve essere modificato. Per esempio, se si chiama questo:

1.hash() 

Si può vedere che il numero 1 risponde infatti al messaggio di hash

+0

Penso che fosse così in 1.8. Ma non sono così sicuro che sia ancora vero nel 1.9. Voglio dire, in 1.9 ottieni un hash gratis. – Candide

+0

Giusto, non volevo dire che devi chiamare esplicitamente hash() sull'oggetto che vuoi usare come chiave - ciò che importa è che l'oggetto implementa il metodo hash() (o 'risponde al messaggio hash ', in gergo OO) –

+5

Deve anche rispondere a 'eql?'. –

3

ci sono già risposte sulla is it possible?.

Una spiegazione, perché non ci sono esempi con numeri interi come chiavi hash.

Le chiavi hash hanno (il più delle volte) un significato. Può essere un nome di attributo e il suo valore (ad esempio :color => 'red' ...).

Quando hai un numero intero come chiave, la tua semantica può essere "primo, secondo ..." (1). Ma allora non usi un hash, ma un array per memorizzare i tuoi valori.

(1) Un controesempio può essere una chiave esterna in un database.

26

Altri guardando le risposte qui potrebbero trovare interessante sapere che un'eccezione si verifica quando si utilizza interi come chiavi simbolo in una Ruby hash{symbol: value}

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

Spiegazione richiesto:

La risposta più semplice perché il primo esempio non riesce è probabilmente che to_sym non è un metodo che è stato implementato per gli interi Fixnum.

Per approfondire la spiegazione del perché, uno dei principali vantaggi dell'uso dei simboli è che due simboli sono in effetti "lo stesso oggetto". O almeno condividono gli stessi ID oggetto.

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

stringhe che sono gli stessi non condividono gli stessi oggetti, e quindi non condividono gli stessi ID oggetto.

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

Come simboli, i numeri interi Fixnum che sono gli stessi avranno gli stessi ID oggetto. Quindi non hai davvero bisogno di convertirli in simboli.

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