Skip to content

Instantly share code, notes, and snippets.

@marcocarvalho
Created September 3, 2012 13:06
Show Gist options
  • Save marcocarvalho/3609215 to your computer and use it in GitHub Desktop.
Save marcocarvalho/3609215 to your computer and use it in GitHub Desktop.
Hash with Initial value
# Ao invés de fazer:
# dentro de uma iteração
h = {}
h[:somekey] = {} if h[:somekey].nil?
h[:somekey][:otherkey] = [] if h[:somekey][:otherkey].nil?
h[:somekey][:otherkey] << item_da_teracao
# Teremos um hash: { somekey: { :otherkey => [1, 2, 3, 4] } }
# Para economizar linhas e lógica poderíamos
h = Hash.new( Hash.new( [] ) )
h[:somekey][:otherkey] << 1
h[:somekey][:otherkey] << 2
h[:somekey][:otherkey] << 3
h[:somekey][:otherkey] << 4
# só que com esse aprouch temos um hash "vazio"
h.size # 0
h.keys # []
# Contudo se acessarmos as keys setadas ele retorna o array certo.
h[:somekey][:otherkey] # [1, 2, 3, 4]
# Bug? Ou braço curtisse minha?
@fnando
Copy link

fnando commented Sep 3, 2012

Pensando melhor, você nem precisa duplicar o Hash que é inner. Se fizer o dup, terá objetos diferentes.

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

outer[:places][:a] += %w[Albuquerque Amsterdam]
outer[:places][:b] += %w[Brasilia Buenos\ Aires]
outer[:places][:b] += %w[Baltimore]

p outer
p outer.size
p outer.keys

@fnando
Copy link

fnando commented Sep 3, 2012

Meh. Use o dup. Ou outer[:food][:a] += %w[apple] irá modificar o hash de lugares. :P

@marcocarvalho
Copy link
Author

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

Resolve :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment