Code
def nested_hash(keys, v, h={})
return subhash(keys, v) if h.empty?
return h.merge(subhash(keys, v)) if keys.size == 1
keys[0..-2].reduce(h) { |g,k| g[k] }.update(keys[-1]=>v)
h
end
def subhash(keys, v)
*first_keys, last_key = keys
h = { last_key=>v }
return h if first_keys.empty?
first_keys.reverse_each.reduce(h) { |g,k| g = { k=>g } }
end
Exemples
h = nested_hash([:a, :b, :c], 14) #=> {:a=>{:b=>{:c=>14}}}
i = nested_hash([:a, :b, :d], 25, h) #=> {:a=>{:b=>{:c=>14, :d=>25}}}
j = nested_hash([:a, :b, :d], 99, i) #=> {:a=>{:b=>{:c=>14, :d=>99}}}
k = nested_hash([:a, :e], 104, j) #=> {:a=>{:b=>{:c=>14, :d=>99}, :e=>104}}
nested_hash([:f], 222, k) #=> {:a=>{:b=>{:c=>14, :d=>99}, :e=>104}, :f=>222}
Observez que la valeur de :d
est remplacée dans le calcul de j
. Notez également que :
subhash([:a, :b, :c], 12)
#=> {:a=>{:b=>{:c=>12}}}
Cela modifie le hachage h
. Si cela n'est pas souhaité, il est possible d'insérer la ligne suivante
f = Marshal.load(Marshal.dump(h))
après la ligne return subhash(keys, v) if h.empty?
et modifier les références ultérieures à h
à f
. Méthodes de la Maréchal peut être utilisé pour créer un copie approfondie d'un hachage afin que le hachage original ne soit pas modifié.