我有一个字符串数组,代表嵌套哈希键的路径,例如
["foo", "bar", "baz"]
我想创建一个函数,该函数接受Array和一个值,并为Array中提供的键设置值,因此当我在示例中调用它时,它将为
设置值 Hash["foo"]["bar"]["baz"]
。
有没有一种方法可以做到这一点。有没有一种方法可以使用#inject将Array的元素链接到对哈希键的调用中?
我们非常感谢您的帮助。
要指定问题:
我有以下代码:
def anonymize_data_hash(data, path=[])
if data.is_a?(Hash)
data.each do |key, value|
anonymize_data_hash(value, path + [key])
end
elsif data.is_a?(Array)
data.each do |value|
anonymize_data_hash(value, path)
end
else
path = path.clone
key = path.shift
path = (path + [data]).map(&:to_s)
send("#{key}")[path] = "xxxxxx"
save
end
end
anonymize_data_hash方法将方法(属性)调用发送到已序列化哈希的模式。路径是一个字符串数组。为了使上述功能正常工作,我需要将字符串数组转换为嵌套的Hash调用。
哈希已经存在,我需要使用数组中给定的值来访问它。 谢谢您的帮助。
答案 0 :(得分:5)
您可以使用更新的方法Hash#dig
(ruby 2.3+)来访问嵌套的哈希,然后在其上设置值:
# ideally this might be a method on Hash, so you wouldn't need to pass it in
def deep_set(hash, path, value)
*path, final_key = path
to_set = path.empty? ? hash : hash.dig(*path)
return unless to_set
to_set[final_key] = value
end
hash = {
"foo" => {
"bar" => { }
}
}
deep_set(hash, ["foo", "bar", "baz"], "xxxxxx")
deep_set(hash, ["baz"], "yyyyyy")
deep_set(hash, ["foo", "baz", "bar"], "zzzzzz")
puts hash
# => {"foo"=>{"bar"=>{"baz"=>"xxxxxx"}}, "baz"=>"yyyyyy"}
答案 1 :(得分:2)
Simple Lime的解决方案要求首先使用格式良好的哈希。如果散列的添加依赖于此,则高度依赖于输入数据及其顺序来确定是否添加了值(例如,示例中的“ zzzzzz”)。您可能想要(重新)定义哈希的default_proc
,以动态创建哈希的结构。这是一个示例:
def nest(array, value)
hash = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }
hash.dig(*array[0..-2])[array.fetch(-1)] = value
hash
end
nest ["foo", "bar", "baz"], :test
# => {"foo"=>{"bar"=>{"baz"=>:test}}}
既然哈希已经存在,我建议对其default_proc
进行适当的初始化。
hash = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }
如果这不可能,您以后仍然可以覆盖它
hash = {} # unchange initialisation
hash.default_proc = -> (h, k) { h[k] = Hash.new(&h.default_proc) }
def nest(hash, array, value)
hash.dig(*array[0..-2])[array.fetch(-1)] = value
hash
end
nest hash, ["foo", "bar", "baz"], :test
# => {"foo"=>{"bar"=>{"baz"=>:test}}}
希望您也能找到帮助。