摆脱嵌套哈希中的“重复项”

时间:2019-08-01 19:56:23

标签: ruby-on-rails ruby

我有一个嵌套的哈希:

given =  {
  "AA" => {
     :GE => nil,
    "GE" => "successful",
     :GR => nil,
     :ZG => nil,
    "ZG" => "successful",
  },
  "BB" => {
    :MM => nil,
    "MM" => "successful",
     :GR => nil,
     :ZZ => nil,
    "ZZ" => "successful",
  }
}

,我的目标是将其转换为新的哈希,而无需重复。 :GE /“ GE”和:ZG /“ ZG”等。

goal = {
  "AA" => {
    :GE => "successful",
    :GR => nil,
    :ZG => "successful",
  },
  "BB" => {
    :MM => "successful",
     :GR => nil,
    :ZZ => "successful",
  }
}

我的尝试是使用Rails方法index_by

given.map do |key, value|
  value.index_by {|r| value[r]}
end

或使用

given.each { |key,value| temp_hash = {} (value.each { |va| va[0].each { |k,v| temp_hash|key| << val }}) given_hash[k.to_sym] = temp_hash if given.has_key?(k.to_sym)} 

但是我有点卡住了。任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

我假设在{ :GE => nil, "GE" => "successful" }的情况下,您要使用第一个真实值(“成功”)并确保键是符号:

result = given.transform_values do |inner_hsh|
  inner_hsh.group_by do |k,v|
    k.to_sym
  end.transform_values do |key_vals|
    key_vals.to_h.values.find(&:itself)
  end
end

答案 1 :(得分:1)

假设@max的假设是正确的,并且内部哈希中键的顺序也不重要,这是产生所需返回值的另一种方法。

given.each_with_object({}) do |(k,v),h|
  h[k] = v.sort_by { |_,w| w.nil? ? 1 : 0 }.uniq { |m,_| m.to_s }.to_h
end
  #=> {"AA"=>{"GE"=>"successful", "ZG"=>"successful", :GR=>nil},
  #    "BB"=>{"MM"=>"successful", "ZZ"=>"successful", :GR=>nil}} 

请参见Array#uniq,尤其是这样的句子:“依次遍历自我,并保持第一次出现。”

对于

k = "AA"
v = { :GE=>nil, "GE"=>"successful", :GR=>nil, :ZG=>nil, "ZG"=>"successful" }

我们计算

a = v.sort_by { |_,w| w.nil? ? 1 : 0 }
  #=> [["GE", "successful"], ["ZG", "successful"],
  #    [:GE, nil], [:GR, nil], [:ZG, nil]] 
b = a.uniq { |m,_| m.to_s }
  #=> [["GE", "successful"], ["ZG", "successful"], [:GR, nil]] 

因为"GE":GE之前,而"ZG":ZG之前。最后,

h[k] = b.to_h
  #=> {"GE"=>"successful", "ZG"=>"successful", :GR=>nil}