2013-12-12 118 views
0

我想通過哈希中的一個鍵合併兩個哈希陣列。舉例來說,如果我有:合併兩個哈希陣列

local = [{:name => 'foo', :values => [2, 7], :desc => 'my foo'}, {:name => 'bar', :values => [3, 8], :desc => 'my bar'}] 
remote = [{:name => 'baz', :values => [4, 1], :desc => 'this baz'}, {:name => 'foo', :values => [5, 7], :desc => 'this foo'}] 

我想合併爲:

[{:name => 'foo', :values => [2, 5, 7], :desc => 'my foo'}, {:name => 'bar', :values => [3,8], :desc => 'my bar'}, {:name => 'baz', :values => [4,1], :desc => 'this baz'}] 

我怎樣才能做到這一點?

+0

其中的價值':desc'你想合併後保留..? –

+0

爲什麼'{:name =>'foo',:values => [2,5,7],:desc =>'my foo'}'not'{:name =>'foo',:values => [ 2,5,7],:desc =>'這個foo'}'? –

回答

1

作爲一種變體(我覺得你得到了一個線索):

local = [{:name => 'foo', :values => [2, 7], :desc => 'my foo'}, {:name => 'bar', :values => [3, 8], :desc => 'my bar'}] 
remote = [{:name => 'baz', :values => [4, 1], :desc => 'this baz'}, {:name => 'foo', :values => [5, 7], :desc => 'this foo'}] 

p (local + remote) 
    .group_by{|el| el[:name]} 
    .map{|_,el| el.inject{|h, e| h[:values] |= e[:values]; h}} 
# => [{:name=>"foo", :values=>[2, 7, 5], :desc=>"my foo"}, {:name=>"bar", :values=>[3, 8], :desc=>"my bar"}, {:name=>"baz", :values=>[4, 1], :desc=>"this baz"}] 
+0

這看起來很有趣。難道不能用'Hash#merge'來管理'inject'部分嗎? –

0

我們假設這段代碼是這樣做的。

def deep_merge a1, a2 
    r = [] 
    a1.each do| v1 | 
     p v1 
     v = v1.dup 
     a2.map! do| v2 | 
     if v2[ :name ] == v[ :name ] 
      v[ :values ] |= v2[ :values ] 
      nil 
     else 
      v2 
     end 
     end.compact! 
     r << v 
    end 
    a2.compact.map do| v2 | 
     r << v2 
    end 
    r 
end 

local = [{:name => 'foo', :values => [2, 7], :desc => 'my foo'}, {:name => 'bar', :values => [3, 8], :desc => 'my bar'}] 
remote = [{:name => 'baz', :values => [4, 1], :desc => 'this baz'}, {:name => 'foo', :values => [5, 7], :desc => 'this foo'}] 

pp = deep_merge local, remote 

# => [{:name=>"foo", :values=>[2, 7, 5], :desc=>"my foo"}, {:name=>"bar", :values=>[3, 8], :desc=>"my bar"}, {:name=>"baz", :values=>[4, 1], :desc=>"this baz"}]