Использование целых чисел в качестве ключей хеша - PullRequest
48 голосов
/ 08 октября 2011

Целесообразно ли использовать целые числа в качестве ключей в хэше Ruby?

Каждый пример из документации показывает строку или символ, используемый в качестве ключа, но не целое число.

Внутренне, будут ли целые числа как-то преобразованы в строки? Я видел противоречивую информацию по этому вопросу.

Другими словами, есть ли существенный недостаток использования целочисленных ключей для хеша?

Ответы [ 4 ]

57 голосов
/ 08 октября 2011

конечно, вы можете использовать целые числа в качестве ключей ...

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

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

=>

one
two
there

irb твой друг! попробуй ..


На самом деле вы можете использовать любой объект Ruby в качестве ключа (или значения). Обычно мы не думаем об использовании таких хэшей, но это может быть весьма полезно.

43 голосов
/ 25 октября 2015

Другим, ищущим ответы здесь, может быть интересно узнать, что исключение происходит, когда вы используете целые числа в качестве символьных ключей в Ruby хэше {symbol: value}

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

Запрошенное объяснение:

Простейший ответ на вопрос о том, почему первый пример дает сбой, вероятно, заключается в том, что to_sym не является методом, который был реализован для Fixnum целых чисел.

Чтобы углубиться в объяснение, почему это так, одно из главных преимуществ использования символов состоит в том, что два символа фактически являются "одним и тем же объектом". Или, по крайней мере, они имеют одинаковые идентификаторы объектов.

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

Строки, которые являются одинаковыми, не используют одни и те же объекты и, следовательно, не имеют одинаковые идентификаторы объектов

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

Как и символы, одинаковые целые числа Fixnum будут иметь одинаковые идентификаторы объектов. Поэтому вам не нужно конвертировать их в символы.

one = 1
=> 1
uno = 1
=> 1
one.object_id
=> 3
one.object_id == uno.object_id
=> true
9 голосов
/ 08 октября 2011

Единственное требование для использования объекта в качестве хеш-ключа заключается в том, что он должен отвечать на хеш сообщения с помощью хеш-значения, и значение хеш-функции для данного ключа не должно изменяться.Например, если вы позвоните по этому номеру:

1.hash()

Вы увидите, что число 1 действительно отвечает на хеш-сообщение

3 голосов
/ 09 июня 2012

Уже есть ответы о is it possible?.

Объяснение, почему нет примеров с целыми числами в качестве хэш-ключей.

Хэш-ключи имеют (в большинстве случаев) значение. Это может быть имя атрибута и его значение (например, :color => 'red' ...).

Когда у вас в качестве ключа целое число, ваша семантика может быть «первым, вторым ...» (1). Но тогда вы используете не хеш, а массив для хранения ваших значений.

(1) Контрпримером может быть внешний ключ в базе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...