Pergunta

Criando hashes de hashes em Ruby permite pesquisas dimensionais convenientes dois (ou mais). No entanto, quando se insere uma necessidade sempre verificar se o primeiro índice já existe no hash. Por exemplo:

h = Hash.new
h['x'] = Hash.new if not h.key?('x')
h['x']['y'] = value_to_insert

Seria preferível fazer o seguinte, onde o novo Hash é criado automaticamente:

h = Hash.new
h['x']['y'] = value_to_insert

Da mesma forma, quando se olha-se um valor em que o primeiro índice já não existir, seria preferível se nil é retornado ao invés de receber um método não definido para erro '[]'.

looked_up_value = h['w']['z']

Pode-se criar um Hash invólucro de classe que tem esse comportamento, mas existe um já existente uma linguagem Ruby para realizar esta tarefa?

Foi útil?

Solução

Você pode passar a função Hash.new um bloco que é executado para produzir um valor padrão no caso do valor consultado ainda não existe:

h = Hash.new { |h, k| h[k] = Hash.new }

Claro, isso pode ser feito de forma recursiva.

/ EDIT: Uau, há um artigo responder a esta pergunta muito.

Por uma questão de exaustividade, aqui está a solução do artigo para hashes profundidade arbitrária:

hash = Hash.new(&(p=lambda{|h,k| h[k] = Hash.new(&p)}))

Os créditos vão para Kent de Dados Noise .

Outras dicas

Autovivification, como é chamado, é uma bênção e uma maldição. O problema pode ser que se você "olhar" para um valor antes de ser definido, você está preso com esse hash vazio no slot e você precisa podar-lo mais tarde.

Se você não se importa um pouco de anarquia, você pode sempre congestionamento na ou-iguala declarações de estilo que lhe permitirá construir a estrutura esperada como você consultá-lo:

((h ||= { })['w'] ||= { })['z']
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top