从哈希数组中构建哈希数组

时间:2015-08-05 17:48:10

标签: ruby hash

我有以下内容:

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(在前两行代码中定义)?

3 个答案:

答案 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}]