Usage of integers as hash keys

35,831

Solution 1

of course you can use integers as keys...

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

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

=>

one
two
there

irb is your friend! try it..


In fact you can use any Ruby object as the key (or the value). We usually don't think about using Hashes like this, but it could be quite useful.

Edit: As Óscar López points out, the object just has to respond to .hash for it to work as a key in a Ruby Hash.

Solution 2

Others looking at the answers here might find it interesting to know that an exception happens when you use integers as symbol keys in a Ruby hash {symbol: value}

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

Requested Explanation:

The simplest answer for why the first example fails is probably that to_sym is not a method that's been implemented for Fixnum integers.

To go more in depth to maybe explaining why that is, one of the main benefits to using symbols is that two symbols are in fact "the same object". Or at least they share the same object ids.

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

Strings that are the same do not share the same objects, and therefore do not share the same object ids.

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

Like symbols, Fixnum integers that are the same will have the same object ids. Therefore you don't really need to convert them into symbols.

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

Solution 3

The only requirement for using an object as a hash key is that it must respond to the message hash with a hash value, and the hash value for a given key must not change. For instance, if you call this:

1.hash()

You can see that the number 1 indeed responds to the hash message

Solution 4

There are already answers about the is it possible?.

An explanation, why there are no examples with integers as Hash-keys.

Hash-keys have (most of the times) a meaning. It may be an attribute name and its value (e.g. :color => 'red'...).

When you have an integer as a key, your semantic may be 'first, second ...' (1). But then you don't use a hash, but an array to store your values.

(1) A counterexample may be a foreign key in a database.

Share:
35,831
timpone
Author by

timpone

Updated on July 09, 2021

Comments

  • timpone
    timpone almost 3 years

    Is it appropriate to use integers as keys in a Ruby hash?

    Every example from documentation shows a string or symbol being used as a key, but never an integer.

    Internally, would integers somehow get converted to strings? I have seen some conflicting information on the subject.

    In other words, is there any significant disadvantage to using integer keys to a hash?

  • Candide
    Candide over 12 years
    I think it used to be so in 1.8. But I'm not so sure it's still true in 1.9. I mean, in 1.9 you get a hash for free.
  • Óscar López
    Óscar López over 12 years
    Right, I didn't mean to say that you have to explicitly call hash() on the object you want to use as a key - what matters is that the object implements the hash() method (or 'responds to the hash message', in OO parlance)
  • Jörg W Mittag
    Jörg W Mittag over 12 years
    It also has to respond to eql?.
  • Bobby Adams
    Bobby Adams almost 8 years
    One thing I find interesting about hash literals with numeric keys is that you cannot use the syntax {1:'one', 2:'two'}. I guess that syntax assumes every key is a symbol, which integers are not.
  • Tilo
    Tilo about 4 years
    this is a peculiarity of the Ruby 1.9 Hash syntax. This is not a general limitation of the Hash class..
  • Tilo
    Tilo almost 3 years
    This is just a peculiarity of the "new" Ruby hash syntax, which uses symbols as keys, and was introduced in Ruby 1.9. It is not a limitation in Ruby's Hash implementation. This syntax is only applicable if you want to have symbols as keys, e.g. {this: 'one', that: 'two'}. It is just a subset of what the Hash class supports.
  • duhaime
    duhaime over 2 years
    Ruby is the jankiest language I've ever worked with