This question is the inverse of this question.
Given a nested hash like
{ :a => { :b => {:c => 1, :d => 2}, :e => 3, }, :f => 4, }
what is the best way to convert it into a flat hash like
{ [:a, :b, :c] => 1, [:a, :b, :d] => 2, [:a, :e] => 3, [:f] => 4, }
Another way:
def flat_hash(h,f=[],g={}) return g.update({ f=>h }) unless h.is_a? Hash h.each { |k,r| flat_hash(r,f+[k],g) } g end h = { :a => { :b => { :c => 1, :d => 2 }, :e => 3 }, :f => 4 } flat_hash(h) #=> {[:a, :b, :c]=>1, [:a, :b, :d]=>2, [:a, :e]=>3, [:f]=>4}
Very similar to Adiel Mittmann's solution
def flat_hash(h, k = []) new_hash = {} h.each_pair do |key, val| if val.is_a?(Hash) new_hash.merge!(flat_hash(val, k + [key])) else new_hash[k + [key]] = val end end new_hash end
Edit: Refactored for elegance. Should be almost as fast.
def flat_hash(hash, k = []) return {k => hash} unless hash.is_a?(Hash) hash.inject({}){ |h, v| h.merge! flat_hash(v[-1], k + [v[0]]) } end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With