2010-07-13 5 views
2

Je cherche une solution comment écrire la fonction format qui prendra en argument une chaîne ou un hachage imbriqué et retournera la version aplatie de celle-ci avec le chemin comme une clé.Comment changer le format des hachages imbriqués

arg = "foo" 
format(arg) # => { "hash[keys]" => "foo" } 

arg = {:a => "foo", :b => { :c => "bar", :d => "baz" }} 
format(arg) # => { "hash[keys][a]" => "foo", "hash[keys][b][c]" => "bar", "hash[keys][b][d]" => "baz" } 
+0

Je ne pense pas que la méthode format() aurait accès au nom de votre argument. (En d'autres termes, comment formater() sait-il placer "[acteur]' après "événement"?) – sarnold

Répondre

1
def hash_flatten h 
    h.inject({}) do |a,(k,v)| 
    if v.is_a?(Hash) 
     hash_flatten(v).each do |sk, sv| 
     a[[k]+sk] = sv 
     end 
    else 
     k = k ? [k] : [] 
     a[k] = v 
    end 
    a 
    end 
end 

def format h 
    if h.is_a?(Hash) 
    a = hash_flatten(h).map do |k,v| 
     key = k.map{|e| "[#{e}]"}.join 
     "\"event[actor]#{key}\" => \"#{v}\"" 
    end.join(', ') 
    else 
    format({nil => h}) 
    end 
end 

arg = "sth" 
puts format(arg) 
# => "event[actor]" => "sth" 

arg = {:a => "sth", :b => { :c => "sth else", :d => "trololo" }} 
puts format(arg) 
# => "event[actor][a]" => "sth", "event[actor][b][c]" => "sth else", "event[actor][b][d]" => "trololo" 
Questions connexes