2011-02-16 68 views
2
array1 = { "d1" => 2, "d2" => 3} 
array2 = { "d1" => 3, "d3" => 10} 

我想這一點:
array3 = { "d1" => 5, "d2" => 3, "d3" => 10}加起來值哈希

我想這一點,這是行不通的。我得到的錯誤:「NoMethodError:未定義的方法`+」的零:NilClass」

array3 = {} 
array1.each {|key, count| array3[key] += count} 
array2.each {|key, count| array3[key] += count} 
+1

如果您關注的是簡潔,你可以改變這:`array3 = array1.merge(array2){| _,v1,v2 | v1 + v2}` – harbichidian 2011-02-16 02:53:14

回答

4

你得到的錯誤,因爲array1.each試圖訪問array3['d1'],這還不存在,所以它返回值爲nil。您只需要更具體地定義array3,使用Hash.new來指示它將0默認分配給所有密鑰。

array3 = Hash.new(0)
array1.each {|key, count| array3[key] += count}
array2.each {|key, count| array3[key] += count}

小心前進,但:你傳遞作爲默認值的對象可以被修改,所以,如果你寫my_hash = Hash.new(Array.new); my_hash[:some_key] << 3然後接收默認所有鍵價值將共享相同的對象。這是Ruby中那些奇怪的陷阱之一,在這種情況下,您會想要使用塊版本Hash.new

+0

唯一的區別是「array3 = Hash.new 0」與「array3 = {}」,爲什麼你的版本工作,我的沒有。 – user612308 2011-02-16 02:39:34

+0

`{}`與'Hash.new()`相同,但是`Hash.new`可以採用一個「默認值」,在這種情況下爲0,可以指定任何尚未給出的鍵的值一個值呢。 – harbichidian 2011-02-16 02:41:48

+0

有道理,謝謝。如果我想初始化array3中的一個元素到一個特定的值,其餘的爲0,我可以在一行而不是2嗎? `array3 = Hash.new 0 array3 [「d5」] = 12` – user612308 2011-02-16 02:56:29

1

用戶,你必須初始化第二陣列中不存在的價值的關鍵:

irb(main):007:0> array1 = {"d1" => 2, "d2" => 3} 
=> {"d1"=>2, "d2"=>3} 
irb(main):008:0> array2 = {"d1" => 3, "d3" => 10} 
=> {"d1"=>3, "d3"=>10} 
irb(main):009:0> array3 = {} 
=> {} 
irb(main):010:0> array1.each {|key, count| array3[key] = (array3[key] || 0) + count} 
=> {"d1"=>2, "d2"=>3} 
irb(main):011:0> array2.each {|key, count| array3[key] = (array3[key] || 0) + count} 
=> {"d1"=>3, "d3"=>10} 
irb(main):012:0> array3 
=> {"d1"=>5, "d2"=>3, "d3"=>10} 
irb(main):013:0> 
2

它更simplier

=> h1 = { "a" => 100, "b" => 200 } 
{"a"=>100, "b"=>200} 
=> h1 = { "a" => 100, "b" => 200 } 
{"b"=>254, "c"=>300} 
=> h1.merge(h2) {|key, oldval, newval| newval + oldval} 
{"a"=>100, "b"=>454, "c"=>300} 

它在覈心1.8.7無證但你可以在這裏閱讀更多: http://www.ruby-doc.org/core/classes/Hash.src/M000759.html

它適用於這兩個版本

0

如果所有的在你的散列是整數你可以使用這一招,它使用的事實,string.to_i給出零

hash.to_a.flatten.inject{|sum, n| sum.to_s.to_i + n.to_s.to_i }