我有一个问题,我如何合并两个哈希的包含,例如
[ {:user =>“Maria”,:alerts => {:rfc =>“此rfc无效”}}, {:user =>“Juan”,:alerts => {:email =>“此电子邮件…
基于简单索引的方法可能如下所示:
array_1 = [ {:user=>"Maria", :alerts=>{:rfc=>"This rfc is invalid"}}, {:user=>"Juan", :alerts=>{:email=>"This email is invalid"}} ] array_2 = [ {:user=>"Maria", :alerts=>{:income_in_the_mean=>true, :credit_in_the_mean=>true}}, {:user=>"Juan", :alerts=>{:income_in_the_mean=>false, :credit_in_the_mean=>true}} ] array_1.zip(array_2).map { |item_1, item_2| item_1.deep_merge(item_2) } #=> [ # {:user=>"Maria", :alerts=>{:rfc=>"This rfc is invalid", :income_in_the_mean=>true, :credit_in_the_mean=>true}}, # {:user=>"Juan", :alerts=>{:email=>"This email is invalid", :income_in_the_mean=>false, :credit_in_the_mean=>true}} # ]
运用 Array#zip 和Rails #deep_merge 。为此,数组必须具有相同的大小,并且要合并的元素必须位于相同的索引位置。
Array#zip
#deep_merge
这是一个纯Ruby解决方案。
arr = [ [ {:user=>"Maria", :alerts=>{:rfc=>"This rfc is invalid"}}, {:user=>"Juan", :alerts=>{:email=>"This email is invalid"}} ], [ {:user=>"Maria", :alerts=>{:income_in_the_mean=>true, :credit_in_the_mean=>true}}, {:user=>"Juan", :alerts=>{:income_in_the_mean=>false, :credit_in_the_mean=>true}} ] ]
arr.flatten.group_by { |h| h[:user] }.map do |user,a| { user: user, alerts: a.reduce({}) { |h,g| h.merge(g[:alerts]) } } end #=> [{:user=>"Maria", # :alerts=>{:rfc=>"This rfc is invalid", :income_in_the_mean=>true, # :credit_in_the_mean=>true}}, # {:user=>"Juan", # :alerts=>{:email=>"This email is invalid", :income_in_the_mean=>false, # :credit_in_the_mean=>true}}]
注意:
arr.flatten.group_by { |h| h[:user] } #=> {"Maria"=>[{:user=>"Maria", :alerts=>{:rfc=>"This rfc is invalid"}}, # {:user=>"Maria", :alerts=>{:income_in_the_mean=>true, # :credit_in_the_mean=>true}}], # "Juan" =>[{:user=>"Juan", :alerts=>{:email=>"This email is invalid"}}, # {:user=>"Juan", :alerts=>{:income_in_the_mean=>false, # :credit_in_the_mean=>true}}]}
arr 当然可以是任何尺寸。
arr
出于好奇,普通的旧红宝石解决方案:
[h1 + h2].each_with_object(Hash.new { |h, k| h[k] = {} }) do |h, acc| acc[h[:user]].merge!(h) { |_, v1, v2| v1.merge(v2) rescue v1 } end.values