我试图找到一种有效方法来使用新值更新哈希数组,但只更新与原始值不同的值。Ruby - 使用新值更新哈希值,但仅在与原始值不同时更新
编辑 - 添加的下方CodeBunk:http://codebunk.com/b/83947000/
例如:
h1 = { foo: "a", bar: "b" }
h2 = { foo: "a", bar: "c" }
h3 = { foo: "h", bar: "e" }
h4 = { foo: "s", bar: "b" }
h5 = { foo: "a"}
h6 = { foo: "y"}
h7 = { bar: "b"}
h8 = { bar: "z"}
hashes = [h1, h2, h3, h4, h5, h6, h7, h8]
original = { foo: "a", bar: "b" }
updated = { foo: "x", bar: "f" }
hashes.each do |h|
# magic?
end
# result:
# h1.insepct #=> { foo: "x", bar: "f" }
# Both "foo" and "bar" change because they both matched their original values;
# h2.insepct #=> { foo: "x", bar: "c" }
# Only "foo" changes; "bar" does NOT change because it has a value differnt than the original
# h3.insepct #=> { foo: "h", bar: "e" }
# Neither "foo" nor "bar" change because neither value matched the original
# h4.insepct #=> { foo: "s", bar: "f" }
# Only "bar" changes; "foo" does not change because it has a value different than the original
# h5.inspect #=> { foo: "x" }
# "foo" changes as it matched the original value; hash does not include "bar"
# h6.inspect #=> { foo: "y" }
# "foo" change; hash does not include "bar"
# h7.inspect #=> { bar: "f" }
# "bar" changes as it matched the original value; hash does not include "foo"
# h8.inspect #=> { bar: "z" }
# "bar" change; hash does not include "foo"
到目前为止,我只能够使用多个嵌套的循环来实现这一目标。我真的希望有一个更好的办法...
编辑2 - 这是我目前的解决方案,我想加以改进:
h1 = { foo: "a", bar: "b" }
h2 = { foo: "a", bar: "c" }
h3 = { foo: "h", bar: "e" }
h4 = { foo: "s", bar: "b" }
h5 = { foo: "a"}
h6 = { foo: "y"}
h7 = { bar: "b"}
h8 = { bar: "z"}
hashes = [h1, h2, h3, h4, h5, h6, h7, h8]
legend = {}
original_attrs = { foo: "a", bar: "b" }
updated_attrs = { foo: "x", bar: "f" }
updated_attrs.each do |k, v|
legend[k] = { original_value: original_attrs[k], new_value: v }
end
hashes.each do |hsh|
legend.each do |legend_key, legend_value|
if hsh.has_key?(legend_key) && hsh[legend_key] == legend_value[:original_value]
hsh[legend_key] = legend_value[:new_value]
end
end
end
logger.debug "hashes: #{hashes}"
# hashes: [
# {:foo=>"x", :bar=>"f"},
# {:foo=>"x", :bar=>"c"},
# {:foo=>"h", :bar=>"e"},
# {:foo=>"s", :bar=>"f"},
# {:foo=>"x"},
# {:foo=>"y"},
# {:bar=>"f"},
# {:bar=>"z"}
# ]
如果你不介意的突变哈希,你的代码很好,因为它很经济易读。一个小点:有些人喜欢写'如果'而不是'如果; ; end'。 –