class SearchNestedHashByValue
def key_for(h, str, trail=[])
h.each_pair do |k, v|
if v == str
trail << k
return true
elsif v.is_a?(Hash)
return trail if key_for(v, str, trail << k)
end
end
false
end
end
locale_file = {:'sv-SE' => {:lang => 'test', :txt => {:hej => 'hej', :hello => "Hello"}}}
s = SearchNestedHashByValue.new
puts s.key_for(locale_file, "Hello").join('.') # => sv-SE.txt.hello
puts s.key_for(locale_file, "Hell").inspect # => false
Refactorings
No refactoring yet !
Adam
October 8, 2008, October 08, 2008 03:48, permalink
I get the feeling you are reinventing the wheel here. Nevertheless, keeping with what you have:
class Locale < Struct.new(:locale, :language, :text)
def include?(string)
text.index(string)
end
def to_key(string)
[ locale, language, text.index(string) ].join('.') if include?(string)
end
end
class Internationalization
def initialize(locale_file)
@locales = locale_file.map do |locale,attributes|
Locale.new(locale, attributes[:lang], attributes[:txt])
end
end
def key_for(string)
if locale = @locales.find { |locale| locale.include?(string) }
locale.to_key(string)
else
false
end
end
end
>> i18n = Internationalization.new(locale_file)
=> #<Internationalization:0x66b48 @locales=[#<struct Locale locale=:"sv-SE", language="test", text={:hello=>"Hello", :hej=>"hej"}>]>
>> i18n.key_for("Hello")
=> "sv-SE.test.hello"
>> i18n.key_for("Hell")
=> false
Search nested hash on their value and return the path as i18n key, aka 'sv-SE.txt.hello'