基于ruby中的散列键和值合并多维哈希数组

时间:2015-04-08 07:31:36

标签: ruby-on-rails ruby arrays multidimensional-array hash

我有一个数组,我希望将id键的值与多维数组中的其他哈希数组匹配,

input = [ 
  [ {"id"=>"1","name"=>"a"},
    {"id"=>"2","name"=>"b"},
    {"id"=>"3","name"=>"c"},
    {"id"=>"4","name"=>"d"},
    {"id"=>"5","name"=>"e"},
    {"id"=>"6","name"=>"f"}
  ],
  [ {"id"=>"3","hoby"=>"AA"},
    {"id"=>"3","hoby"=>"BB"},
    {"id"=>"1","hoby"=>"CC"},
    {"id"=>"1","hoby"=>"DD"},
    {"id"=>"4","hoby"=>"EE"}
  ],
  [ {"id"=>"1","language"=>"A"},
    {"id"=>"1","language"=>"B"},
    {"id"=>"2","language"=>"B"},
    {"id"=>"2","language"=>"C"},
    {"id"=>"6","language"=>"D"}
  ] 
]

我需要数组输出,如

output = [ 
  {"id"=>"1","name"=>"a","id"=>"1","hoby"=>"CC","id"=>"1","language"=>"A","id"=>"1","language"=>"B"},
  {"id"=>"2","name"=>"b","id"=>"2","language"=>"B"},
  {"id"=>"3","name"=>"c","id"=>"3","hoby"=>"AA","id"=>"3","hoby"=>"BB"},
  {"id"=>"4","name"=>"d","id"=>"4","hoby"=>"EE"},
  {"id"=>"5","name"=>"e"},
  {"id"=>"6","name"=>"f","id"=>"6","language"=>"D"}
]

我为此编写了代码,

len = input.length - 1
output = []
input[0].each do |value,index|
  for i in 1..len
    input[i].each do |j|
      if value["id"] == j["id"]
        output << value.merge(j)
      end
    end
  end
end

但我的输出数组错误。多维数组中可能有任意数量的子数组。

感谢,

2 个答案:

答案 0 :(得分:2)

首先 - 在具有相同键的哈希中不可能有两个元素。将值分配给某个键时,将使用新值的相同键的下一个赋值覆盖前一个键。

让我们考虑一下这个例子:

hash = {}
hash["id"] = 1
hash["id"] = 3
hash["id"] = 5

您期望hash["id"]的输出是多少? 135[1, 3, 5]The way the Hash in ruby works它将输出5,因为这是唯一键的最后一次分配。

话虽如此,不可能在哈希中存储多个匹配项,但您可以尝试使用以下内容进行处理:

input.flatten
     .group_by { |h| h["id"] }
     .map do |k, a| 
       a.each_with_object({}) { |in_h, out_h| out_h.merge!(in_h) } 
     end

这将导致哈希:

[{"id"=>"1", "name"=>"a", "hoby"=>"DD", "language"=>"B"}, 
 {"id"=>"2", "name"=>"b", "language"=>"C"}, 
 {"id"=>"3", "name"=>"c", "hoby"=>"BB"}, 
 {"id"=>"4", "name"=>"d", "hoby"=>"EE"}, 
 {"id"=>"5", "name"=>"e"}, 
 {"id"=>"6", "name"=>"f", "language"=>"D"}]

嗯,这不是你想象的哈希,但至少它可能会让你朝某个方向发展。

希望有所帮助!

答案 1 :(得分:1)

也许这可以帮到你。

input = [
  [
  {"id"=>"1","name"=>"a"},
  {"id"=>"2","name"=>"b"},
  {"id"=>"3","name"=>"c"},
  {"id"=>"4","name"=>"d"},
  {"id"=>"5","name"=>"e"},
  {"id"=>"6","name"=>"f"}
  ],
  [
  {"id"=>"3","hoby"=>"AA"},
  {"id"=>"3","hoby"=>"BB"},
  {"id"=>"1","hoby"=>"CC"},
  {"id"=>"1","hoby"=>"DD"},
  {"id"=>"4","hoby"=>"EE"}
  ],
  [
  {"id"=>"1","language"=>"A"},
  {"id"=>"1","language"=>"B"},
  {"id"=>"2","language"=>"B"},
  {"id"=>"2","language"=>"C"},
  {"id"=>"6","language"=>"D"}
  ]
]

通过这种方式,您可以制作“排序”结果。

output = {}
input.flatten.each do |h|
  output[h["id"]] = {} unless output[h["id"]]
  output[h["id"]].merge!(h)
end

output.values
# => [
# =>   {"id"=>"1", "name"=>"a", "hoby"=>"DD", "language"=>"B"},
# =>   {"id"=>"2", "name"=>"b", "language"=>"C"},
# =>   {"id"=>"3", "name"=>"c", "hoby"=>"BB"},
# =>   {"id"=>"4", "name"=>"d", "hoby"=>"EE"},
# =>   {"id"=>"5", "name"=>"e"},
# =>   {"id"=>"6", "name"=>"f", "language"=>"D"}
# => ]

但更好的方法是在输入中使用Hash。你可以定义像hash这样的输入和像key这样的“id”,所以如果你生成数据,你就没有问题要对它进行排序。

像这样的人

{
  "1" => {"name" => "a", "hoby" => "DD", "language" => "B"}
}