我有一个嵌套的哈希:
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)}
但是我有点卡住了。任何帮助将不胜感激!
答案 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}