はそれを行うための3つの方法があります。
ここ
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
(:
はステップ
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}
をマージされ、両方のハッシュに存在するキーの値を決定するためにブロックを使用Hash#updateの形式を使用します別名merge!
)はブロック{ |_,o,v| o+v }
を使用して)両方のハッシュに存在するキーの値を決定します。最初のブロック変数(使用されていないのでローカル変数_
で表すことができます)はキーで、2番目の変数(o
、 "古い"の場合)はh
のキーの値で、3番目のブロック変数はn
"new")は、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] = h[k] + g[k]
h
キーk
を持っていない場合は、右側にh[k]
は、したがって、0
によって置き換えられます。上記のh[k] += g[k]
はに展開されます。
合計値とあなたはRubyのV1.9 +を使用していて、キーが各ハッシュで同じ順序を持つことが保証されている場合は、ハッシュ
に変換し、それを行うことができる第三の方法は、通りです以下の:(上記b
から開始)
["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}
の手順は以下のとおりです。
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 "=> {"スコア "=> 2、"ストローク "=> 146、"ラウンド "=> 3}、...}' 'nil'の値を含む' players'要素で何をしたいのかを説明する必要があります。私はそれらをスキップすることを前提としていましたが、最初は孤独な 'nil'に気付かず、コードにバグがありました。 –