Как я могу собрать хеш с массивами? - PullRequest
1 голос
/ 31 марта 2010

Что я должен сделать для маршала хэша массивов? Следующий код печатает только {}.

s = Hash.new
s.default = Array.new
s[0] << "Tigger"
s[7] << "Ruth"
s[7] << "Puuh"
data = Marshal.dump(s)
ls = Marshal.restore( data )
p ls

Если хеш не содержит массив, он восстанавливается должным образом.

Ответы [ 4 ]

7 голосов
/ 31 марта 2010
s = Hash.new
s.default = Array.new
s[0] << "Tigger"
s[7] << "Ruth"
s[7] << "Puuh"

Этот код изменяет значение по умолчанию 3 раза (что, вероятно, было показано в дампе), но он ничего не хранит в хэше. Попробуйте "put s [8]", он вернет [["Tigger"], ["Ruth"], ["Puuh"]].

Hash.default_proc будет делать то, что вы хотите

s = Hash.new{|hash,key| hash[key]=[] }

Но вы не можете организовать процесс. Это будет работать:

s = Hash.new
s.default = Array.new
s[0] += ["Tigger"]
s[7] += ["Ruth"]
s[7] += ["Puuh"]

Это работает, потому что [] + = ["Tigger"] создает новый массив. Альтернатива, создающая меньше массивов:

s = Hash.new
(s[0] ||= []) << "Tigger"
(s[7] ||= []) << "Ruth"
(s[7] ||= []) << "Puuh"

Создает новый массив только при отсутствии ключа (ноль).

2 голосов
/ 31 марта 2010

Вы можете просто создать свою хеш-структуру при инициализации Hash.new, чтобы избежать такой проблемы

h = Hash.new{ |a,b| a[b] = [] }
h[:my_key] << "my value"
1 голос
/ 31 марта 2010

Вы можете быть введены в заблуждение о том, как работает Hash.default.

Перед вами Marshal.dump распечатайте структуру данных. Это {}. Это потому, что вы объединяете каждую строку в ноль, а не в пустой массив. Код ниже иллюстрирует и решает вашу проблему.

s = Hash.new
s.default = Array.new
s[0] = []
s[0] << "Tigger"
s[7] = []
s[7] << "Ruth"
s[7] << "Puuh"
p s
data = Marshal.dump(s)
ls = Marshal.restore( data )
p ls

Возвращает:

{0=>["Tigger"], 7=>["Ruth", "Puuh"]}
{0=>["Tigger"], 7=>["Ruth", "Puuh"]}

EDIT:

Я вставляю много данных в хеш

Так что, возможно, какой-нибудь вспомогательный код сделает процесс вставки более плавным:

def append_to_hash(hash, position, obj)
  hash[position] = [] unless hash[position]
  hash[position] << obj
end

s = Hash.new
append_to_hash(s, 0, "Tigger")
append_to_hash(s, 7, "Ruth")
append_to_hash(s, 7, "Puuh")
s.default = Array.new // this is only for reading
p s
data = Marshal.dump(s)
ls = Marshal.restore( data )
p ls
0 голосов
/ 31 марта 2010

Поскольку вы не можете использовать Marshall.dump в хэше с процедурой для элемента по умолчанию, вы можете использовать немного более окольный способ добавления к каждому массиву вместо <<:

s = Hash.new
s.default = []
s[0] += [ "Tigger" ]
s[7] += [ "Ruth" ]
s[7] += [ "Pooh" ]
data = Marshal.dump(s)
ls = Marshal.restore(data)
p ls
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...