2014-06-13 43 views
0

考虑以下嵌套哈希:差分之间2不同的嵌套散列红宝石1.8.7

data1 = { 
    "3"=>{"passenger_type"=>"ADT", "the_order"=>"3", "last"=>"JONES", "first"=>"ALENA", "middle"=>nil}, 
    "2"=>{"passenger_type"=>"ADT", "the_order"=>"2", "last"=>"JONES", "first"=>"MAXIM", "middle"=>nil}, 
    "1"=>{"passenger_type"=>"ADTT", "the_order"=>"1", "last"=>"JONES", "first"=>"TODD", "middle"=>nil}} 


data2 = { 
    "3"=>{"first"=>"ALENA", "the_order"=>"3", "middle"=>"", "passenger_type"=>"ADTT", "last"=>"JONES"}, 
    "2"=>{"first"=>"MAXIM", "the_order"=>"2", "middle"=>"", "passenger_type"=>"ADT", "last"=>"JONES"}, 
    "1"=>{"first"=>"TODD", "the_order"=>"1", "middle"=>"", "passenger_type"=>"ADT", "last"=>"JONESS"}} 

输出应该是这样的(两个散列列出的值之间的差):

{"3" => {"passenger_type" => ["ADT", "ADTT"]}, 
"1" => {"passenger_type" => ["ADTT", "ADT"], "last" => ["JONES", "JONESS"]} 

任何您的建议表示感谢,提前致谢。

+0

你是否认为'data1'和'data2'(即所有''''或全部'nil')键的'middle'具有相同的值?如果这是一个疏忽,就不需要回复;编辑完成后,我会删除这条评论... –

+0

是的正确! –

+0

在这种情况下,我不明白为什么'middle => [nil,'']'没有出现在你想要的输出中。请通过编辑来澄清(而不是在评论中)。 –

回答

1

可以使用的Hash#merge,需要一个块的形式,以产生以紧凑的方式所期望的结果:

data1.merge(data2) { |_,ho,hn| 
     ho.merge(hn) { |_,o,n| (o==n||o==''||n=='') ? nil : [o,n] } 
     .delete_if { |_,v| v==nil } } 
    .delete_if { |_,v| v.empty? } 
    #=> {"3"=>{"passenger_type"=>["ADT", "ADTT"]}, 
    # "1"=>{"passenger_type"=>["ADTT", "ADT"], "last"=>["JONES", "JONESS"]}} 
+0

紧凑美人! :) – zx81

0

下面是一些丑陋的代码:

data3 = {} 
data1.each do |k, v| 
    v2 = data2[k] 
    v.each do |item, val| 
    if v2.has_key?(item) then 
     if (val == nil or val == '') and (v2[item] == nil or v2[item] == '') then 
     next 
     end 

     if val != v2[item] then 
     data3[k] ||= {} 
     data3[k][item] = [val, v2[item]] 
     end 
    end 
    end 
end 

puts data3 

打印

{"3"=>{"passenger_type"=>["ADT", "ADTT"]}, "1"=>{"passenger_type"=>["ADTT", "ADT"], "last"=>["JONES", "JONESS"]}} 
+0

不知道主题起始者的要求,所以只是作为一个警告:当data1的键数少于data2时,这不会处理这种情况。也不适用于嵌套更深的哈希。 – twonegatives

+0

这也是有用的加工商, –