2016-11-14 3 views
0

У меня есть массив строк неизвестной длины (но, допустим, до 5). У меня также есть пустой хэш h = {} и значение.Как вставить значения в динамически вложенный хеш?

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

val = 1 
h = {} 
a = ['a', 'b', 'c', 'd'] 
# result I want: 
{ 
    'a' => { 
    'b' => { 
     'c' => { 
     'd' => 1 
     } 
    } 
    } 
} 

Что важно, что некоторые из ключей, возможно, уже существует (создан в итерации цикла раньше). Таким образом, я мог бы:

val = 2 
h = {'a' => {'b' => {'c' => {'d' => 1}}}} 
a = ['a', 'b', 'c', 'e'] 
# result I want: 
{ 
    'a' => { 
    'b' => { 
     'c' => { 
     'd' => 1, 
     'e' => 2 
     } 
    } 
    } 
} 

Любые идеи о том, как это сделать?

ответ

3

Еще раз inject на помощь:

def dredge(hash, list, value = nil) 
    # Snip off the last element 
    *list, tail = list 

    # Iterate through the elements in the path... 
    final = list.inject(hash) do |h, k| 
    # ...and populate with a hash if necessary. 
    h[k] ||= { } 
    end 

    # Add on the final value 
    final[tail] = value 

    hash 
end 

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

Здесь применяется:

h = {} 
a = ['a', 'b', 'c', 'd'] 
dredge(h, a, 1) 
# => {"a"=>{"b"=>{"c"=>{"d"=>1}}}} 

h = {'a' => {'b' => {'c' => {'d' => 1}}}} 
a = ['a', 'b', 'c', 'e'] 

dredge(h, a, 2) 
# => {"a"=>{"b"=>{"c"=>{"d"=>1, "e"=>2}}}} 
+3

Я собирался опубликовать то же самое :-) Вы можете использовать '* список, хвост = list' избежать мутирует' list' – Stefan

+0

Правда, это, вероятно, лучше , Позвольте мне изменить это. – tadman

Смежные вопросы