Как обновить вложенный хэш Ruby внутри цикла? - PullRequest
0 голосов
/ 12 мая 2011

Я создаю вложенный хеш в ruby ​​rexml и хочу обновить хэш при входе в цикл.

Мой код похож на:

hash = {}
doc.elements.each(//address) do |n|
  a = # ... 
  b = # ...
  hash = { "NAME" => { a => { "ADDRESS" => b } } }
end

Когда я выполняю приведенный выше код, хэш перезаписывается, и я получаю только информацию на последней итерации цикла.

Я не хочу использовать следующий способ, поскольку это делает мой код многословным

hash["NAME"] = {}
hash["NAME"][a] = {} 

и так далее ...

Так может кто-нибудь помочь мне с тем, как сделать эту работу ...

Ответы [ 4 ]

0 голосов
/ 12 мая 2011
blk = proc { |hash, key| hash[key] = Hash.new(&blk) }

hash = Hash.new(&blk)

doc.elements.each('//address').each do |n|
  a = # ...
  b = # ...
  hash["NAME"][a]["ADDRESS"] = b
end

По существу создает ленивый экземпляр бесконечно повторяющегося хэша хэшей.

РЕДАКТИРОВАТЬ: Просто подумал о том, что может работать, это проверяется только с парой очень простых хэшей, поэтому могут возникнуть некоторые проблемы.

class Hash
  def can_recursively_merge? other
    Hash === other
  end

  def recursive_merge! other
    other.each do |key, value|
      if self.include? key and self[key].can_recursively_merge? value
        self[key].recursive_merge! value
      else
        self[key] = value
      end
    end
    self
  end
end

Затем используйте hash.recursive_merge! { "NAME" => { a => { "ADDRESS" => b } } } в своем блоке кода.

Это просто рекурсивно объединяет иерархию хешей и любые другие типы, если вы определяете методы recursive_merge! и can_recusively_merge?на них.

0 голосов
/ 12 мая 2011

Вы всегда создаете новый хеш в каждой итерации, который сохраняется в hash.

Просто назначьте ключ непосредственно в существующем hash:

hash["NAME"] = { a => { "ADDRESS" => b } }
0 голосов
/ 12 мая 2011
hash = {"NAME" => {}}

doc.elements.each('//address') do |n|
  a = ...
  b = ...
  hash['NAME'][a] = {'ADDRESS' => b, 'PLACE' => ...}
end
0 голосов
/ 12 мая 2011

Предполагая, что имена уникальны:

hash.merge!({"NAME" => { a => { "ADDRESS" => b } } })
...