2013-03-02 108 views
0

名單在Ruby中,我們可以通過使用merge功能合併散列:合併哈希和不覆蓋內

1.9.3-p194 :038 > h1 = { "a" => 1, "b" => [1] } 
=> {"a"=>1, "b"=>[1]} 
1.9.3-p194 :039 > h2 = { "a" => 2, "b" => [2] } 
=> {"a"=>2, "b"=>[2]} 
1.9.3-p194 :040 > h1.merge(h2) 
=> {"a"=>2, "b"=>[2]} 

合併將覆蓋陣列中的散列裏面,但我想它加入他們的行列。

=> {"a"=>2, "b"=>[1, 2]} 

是否有一個ruby函數或單線程來實現這個功能?

+0

你想要這樣的東西嗎? ruby​​-1.9.2> a = {:car => {:color =>「red」}} => {:car => {:color =>「red」}} ruby​​-1.9.2> b = {:car => {:speed =>「100mph」}} => {:car => {:speed =>「100mph」}} ruby​​-1.9.2> a.merge(b){|鍵,a_val,b_val | a_val.merge b_val} => {:car => {:color =>「red」,:speed =>「100mph」}} – 2013-03-02 10:04:02

+0

如果您有兩個哈希值,選項和默認值,並且想要將默認值合併到選項而不覆蓋現有的密鑰,你真正想要做的是相反的:合併選項默認爲: 選項= defaults.merge(選項) 或者,如果你正在使用Rails,你可以做: options.reverse_merge(默認值) – 2013-03-02 10:06:13

+0

@ X-Factor這個*是*關於選項哈希值,你傳遞給'as_json'的選項哈希值,包含'{except:[:this,:that]}''。我不想重寫'except',我想*添加*到'except'。您的解決方案不考慮陣列。 – alestanis 2013-03-02 10:20:31

回答

8

您可以添加額外的行爲合併方法

h1 = { "a" => 1, "b" => [1] } 
h2 = { "a" => 2, "b" => [2] } 

h1.merge(h2) {|key, first, second| first.is_a?(Array) && second.is_a?(Array) ? first | second : second } 
+0

非常好的解決方案,我不知道你可以傳遞一個塊到'merge'方法。我不知道'Array |陣列'操作員。謝謝! – alestanis 2013-03-02 10:22:28

0

你可以在一個塊傳遞給merge,這看起來好像是特別適用於這樣的情況下設計的。

a = { x: 1, y: [1] } 
b = { x: 2, y: [2] } 
a.merge(b) {|k, a, b| a.is_a?(Array) && b.is_a?(Array) ? a + b : b} 
=> { x: 2, y: [1, 2] } 
+0

如果'a = {x:1,y:[2]}'和'b = {x:2,y:[2]}''會怎麼樣?它會創建'{x:2,y:[2,2]}'!不應該只是[2]而不是[2,2] – 2013-03-02 10:21:40

+0

謝謝!用我的例子,你的解決方案產生'{「a」=> 2,「b」=> [1,2,1]}雖然 – alestanis 2013-03-02 10:21:59

+0

@SybariteManoj它真的取決於他想合併還是連接數組的內容。 – 2013-03-03 01:44:11