以下是這樣做的三種方式。
使用的Hash#update了採用塊,以確定存在於這兩個散列密鑰的值被合併
players.map { |g| g.first.last }.
compact.
each_with_object({}) { |g,h| h.update(g) { |_,o,v| o+v } }
#=> {"score"=>4, "strokes"=>881, "rounds"=>18}
的步驟形式:
a = players.map { |g| g.first.last }
#=> [{"score"=> 2, "strokes"=>146, "rounds"=>3},
# {"score"=> 1, "strokes"=>145, "rounds"=>3},
# {"score"=> 0, "strokes"=>144, "rounds"=>3},
# {"score"=> 0, "strokes"=>144, "rounds"=>3},
# {"score"=> 5, "strokes"=>162, "rounds"=>3},
# nil,
# {"score"=>-4, "strokes"=>140, "rounds"=>3}]
b = a.compact
#=> [{"score"=> 2, "strokes"=>146, "rounds"=>3},
# {"score"=> 1, "strokes"=>145, "rounds"=>3},
# {"score"=> 0, "strokes"=>144, "rounds"=>3},
# {"score"=> 0, "strokes"=>144, "rounds"=>3},
# {"score"=> 5, "strokes"=>162, "rounds"=>3},
# {"score"=>-4, "strokes"=>140, "rounds"=>3}]
b.each_with_object({}) { |g,h| h.update(g) { |_,o,v| o+v } }
#=> {"score"=>4, "strokes"=>881, "rounds"=>18}
這裏,Hash#update
(又名merge!
)使用塊{ |_,o,v| o+v }
)來確定兩個哈希中存在的鍵的值。第一個塊變量(未使用,因此可以用局部變量_
表示)是關鍵,第二個塊(o
,對於「舊」)是h
中的鍵的值,第三個(n
,對於「新」)是g
中密鑰的值。
使用計數散列
players.map { |g| g.first.last }.
compact.
each_with_object(Hash.new(0)) { |g,h| g.keys.each { |k| h[k] += g[k] } }
Hash.new(0)
創建具有零缺省值,由塊變量g
表示一個空的散列。這意味着如果散列h
沒有密鑰k
,則h[k]
返回默認值(但不會更改散列)。以上h[k] += g[k]
擴展爲:
h[k] = h[k] + g[k]
如果h
不具有關鍵k
,h[k]
右側因此由0
取代。
和值,然後轉換爲一個哈希
如果您在使用Ruby V1.9 +和按鍵都保證在每個哈希相同的順序,這是可以做到的第三種方法是如下:
["scores", "strokes", "rounds"].zip(
players.map { |g| g.first.last }.
compact.
map(&:values).
transpose.
map { |arr| arr.reduce(:+) }
).to_h
#=> {"scores"=>4, "strokes"=>881, "rounds"=>18}
的步驟(從上面開始b
)爲:
c = b.map(&:values)
#=> [[ 2, 146, 3],
# [ 1, 145, 3],
# [ 0, 144, 3],
# [ 0, 144, 3],
# [ 5, 162, 3],
# [-4, 140, 3]]
d = c.transpose
#=> [[ 2, 1, 0, 0, 5, -4],
# [146, 145, 144, 144, 162, 140],
# [ 3, 3, 3, 3, 3, 3]]
totals = d.map { |arr| arr.reduce(:+) }
#=> [4, 881, 18]
e = ["scores", "strokes", "rounds"].zip(totals)
#=> [["scores", 4], ["strokes", 881], ["rounds", 18]]
e.to_h
#=> {"scores"=>4, "strokes"=>881, "rounds"=>18}
如果未給定對象'players',它可能是更好將其表示爲散列:'{「Angel Cabrera」=> {「score」=> 2,「strokes」=> 146,「rounds」=> 3},...}。你應該解釋一下你想要處理的元素包含'nil'值的'players'。我認爲他們將被跳過,但最初沒有注意到孤獨'nil',這導致了我的代碼中的一個錯誤。 –