我有一个哈希值,上面写着,
hash = {"lock_version"=>4,
"exhibition_quality"=>false,
"within"=>["FID6", "S2"],
"repository"=>
{"ref"=>"/repositories/2",
"repository"=>{"ref"=>"/repositories/2",
"within"=>["FID6", "S2"]
}
}
此哈希通过另一个函数传递。如何从"within"=>["FID6"、"S5"] 中删除具有模式 FID(在本例中为 FID6(的值,而不会很好地改变原始哈希灰分?这只是哈希的缩短版本,但在其他情况下,哈希值超长,并且"内"键值对多次出现。注意:此程序使用的是 ruby 2.4
我被要求澄清这个问题与我之前提出的问题有何不同,所以这是更多的澄清,因为从那以后我做了更多的工作。这个特定的键值对 "within"=>["FID6", "S2"],现在显示为深度嵌套(整个哈希值大约 2 页长,因此我没有复制和粘贴它(。我无法拆分"存储库"所在的哈希值,因为它似乎嵌套在其他键值中。 我现在要问的是,有没有办法在键值中匹配它,无论现在它有多深。感谢大家的建议。
代码
def defidder(h)
h.each_with_object({}) do |(k,v),h|
h[k] =
case v
when Array
v.reject { |s| s.match?(/AFIDd+z/) } if k == "within"
when Hash
defidder(v)
else
v
end
end
end
例
我在问题中给出的示例中添加了另一层哈希嵌套:
hash = {
"lock_version"=>4,
"exhibition_quality"=>false,
"within"=>["FID6", "S2"],
"repository"=>{
"ref"=>"/repositories/2",
"repository"=>{"ref"=>"/repositories/2"},
"within"=>["FID6", "S2"],
"1more"=>{ a: 1, "within"=>["FID999", "S7"] }
}
}
defidder hash
#=> {
# "lock_version"=>4,
# "exhibition_quality"=>false, "within"=>["S2"],
# "repository"=>{
# "ref"=>"/repositories/2",
# "repository"=>{"ref"=>"/repositories/2"},
# "within"=>["S2"],
# "1more"=>{:a=>1, "within"=>["S7"]
# }
# }
我们可以验证hash
没有突变。
hash
#=> {
# "lock_version"=>4,
# "exhibition_quality"=>false,
# "within"=>["FID6", "S2"],
# "repository"=>{
# "ref"=>"/repositories/2",
# "repository"=>{"ref"=>"/repositories/2"},
# "within"=>["FID6", "S2"],
# "1more"=>{ a: 1, "within"=>["FID999", "S7"] }
# }
# }
假设:
- 数组中只有嵌套哈希,没有哈希。
- 哈希中没有对象。
这适用于您的示例,也适用于我使用上述假设创建的示例:
cloned_hash = Marshal.load(Marshal.dump(hash))
def remove_key_value_pair(key, value, hash)
if hash.key?(key) && hash[key] == value
hash.delete(key)
end
hash.each{|k, v| remove_key_value_pair(key, value, v) if v.is_a? Hash }
end
# call with
remove_key_value_pair("within", ["FID6", "S2"], cloned_hash)
如果哈希有很多嵌套,这将遇到SystemStackError
。