题目来自 codewars,4kyu 级别难度。
Write a simple method for the Hash-class that can get the configuration-value from a JSON-interpreted hash. Its signature is:
Hash.get_value( default, key1, ... )
key1, ... refer to the hash-keys of the JSON-interpreted hash, which is a hash of hash values. If the path of keys is found, it should return the found value, else it should return the default value.
Here are some examples on how to use it:
config = { :files => { :mode => 0x777 }, :name => "config" }
config.get_value( 0x0, :files, :mode ) == 0x777 config.get_value( "", :name ) == "config" config.get_value( 80, :port ) == 80 config.get_value( "cfg", :files, :extension ) == "cfg"
我就贴个 java 风格的 ruby 代码让大家来耻笑吧,坐等楼下的一行流。
class Hash
def get_value(default, *keys)
hash_copy = self.clone
if hash_copy.has_key?(keys[0])
hash_copy = hash_copy[keys[0]]
if hash_copy.is_a?(Hash)
keys.shift
hash_copy.get_value(default, *keys)
elsif keys.size == 1
hash_copy
else
default
end
else
default
end
end
end
我当时写的(现在已经搞不懂为啥这么写了):
class Hash
def get_value( default, *args )
return default if args.empty?
begin
value = self
loop do
break value if args.empty?
break default if !value.respond_to?(:fetch)
value = value.fetch(args.shift)
end
rescue KeyError
default
end
end
end
我说 codewars 怎么这么慢,原来一个 application-225c0ec0f6639a814d4c7e83507cfe55.js 竟然都快 500k 了……
为了一行已丧病,只保证跑通上面四个等式 _ (:з」∠)_
class Hash
def get_value(default, *key_path)
key_path.reduce(self) { |child, key| child.is_a?(Hash) ? child.fetch(key, default) : child }
end
end
fetch(key [, default] ) → obj
fetch(key) {| key | block } → obj
Returns a value from the hash for the given key. If the key can’t be found, there are several options: With no other arguments, it will raise an KeyError exception; if default is given, then that will be returned; if the optional code block is specified, then that will be run and its result returned.
我也来一个吧。
def get_value(default, *args)
eval("self#{args.map{ |arg| "[:#{arg}]" }.join}") || default rescue default
end