我有以下内容:
array_of_hashes = [{"a" => 1, "b" => 2}, {"a" => 3, "b" => 4}]
我想将其转换为:
new_hash = [{"cow" => 1, "dog" => 2}, {"cow" => 3, "dog" => 4}]
我尝试了以下内容:
new_hash = {}
array_of_hashes.each do |a|
new_hash["cow"] = a["a"]
new_hash["dog"] = a["b"]
end
但是,new_hash
只会导致来自array_of_hashes
的第二个哈希:
new_hash = {"cow"=>3, "dog"=>4}
对于需要明确陈述问题的人:
如何将array_of_hashes
映射到new_hash
(在前两行代码中定义)?
答案 0 :(得分:8)
您正在将哈希数组转换为单个哈希。您错过了整个数组部分。
你想要
new_array = []
array_of_hashes.each do |a|
new_hash = {}
new_hash["cow"] = a["a"]
new_hash["dog"] = a["b"]
new_array << new_hash
end
如果你更习惯地写这个,你就会产生这样的东西:
new_array = array_of_hashes.map do |hash|
{ "cow" => hash['a'], "dog" => hash['b'] }
end
答案 1 :(得分:2)
也许这些可以帮助你理解你做错了什么:
您的代码是:
array_of_hashes = [{"a" => 1, "b" => 2}, {"a" => 3, "b" => 4}]
new_hash = {}
array_of_hashes.each do |a|
new_hash # => {}, {"cow"=>1, "dog"=>2}
第一次,new_hash
是{}
。第二次通过{"cow"=>1, "dog"=>2}
。
new_hash["cow"] = a["a"] # => 1, 3
第一次,您将1
分配给与cow
密钥相关联的值,第二次使用3
覆盖该值。
new_hash["dog"] = a["b"] # => 2, 4
这与上面类似。你正在覆盖这些价值观。
new_hash # => {"cow"=>1, "dog"=>2}, {"cow"=>3, "dog"=>4}
end
导致:
new_hash # => {"cow"=>3, "dog"=>4}
相反,你可以写:
new_array = []
你真的想积累到一个数组,而不是哈希,因为哈希不能容纳相同键的多个实例。
array_of_hashes.each do |h|
new_array # => [], [{"cow"=>1, "dog"=>2}]
第一次通过new_array
为空。第二次它有前一个循环的哈希值。
new_array << {
'cow' => h['a'],
'dog' => h['b']
}
将新哈希附加到数组中。
new_array # => [{"cow"=>1, "dog"=>2}], [{"cow"=>1, "dog"=>2}, {"cow"=>3, "dog"=>4}]
你可以看到数组累积了子哈希值。
end
new_array # => [{"cow"=>1, "dog"=>2}, {"cow"=>3, "dog"=>4}]
那就是说,我用一个简单的map
做@meager suggested。
答案 2 :(得分:1)
这与@ meagar的答案基本相同,但我将其包含在内,以展示如何以相当一般的方式实现它。
def replace_em(arr, replacements)
arr.map do |h|
h.each_with_object({}) do |(k,v),g|
g[replacements.key?(k) ? replacements[k] : k] = v
end
end
end
arr = [{ "a"=>1, "b"=>2, "c"=>3 }, { "a"=>3, "b"=>4, "d"=> 5 }]
replacements = { "a"=>"cow", "b"=>"dog", "e"=>"cat" }
replace_em(arr, replacements)
#=> [{"cow"=>1, "dog"=>2, "c"=>3}, {"cow"=>3, "dog"=>4, "d"=>5}]