2012-02-26 13 views
8

私はこのようなハッシュを持っています。ルビーのハッシュ値を集計する

products = {199 =>['Shoes', 59.99], 211 =>['Shirts', 19.99], 245 =>['Hats', 25.99], 689 => ['Coats', 99.99], 712 => ['Beanies', 6.99]} 

商品番号=>[product, price]です。

私は注射方法を使用せずにすべての価格を要約したいと思います。

誰でも教えてください。

+6

それを使用しないための理由ではありませんinject' '理解していません。代わりに、ちょうどそれを読んで、関数型プログラミングスタイルはしばしばより簡潔で、読めるコードにつながることができます。 –

+0

@ NiklasBに同意します。ここで、 'inject' /' reduce'はあなたがそれを理解すれば、あなたのコードをずっとシンプルでよりエレガントにする素晴らしい方法です。 –

答えて

1
sum = 0 
products.each { |key, value| sum += value.last } 
16
products.values.map(&:last).reduce(:+) #=> 212.95 
+1

純粋なルビーで配列にsumメソッドがありません – Fivell

+0

そのために '(reduce:&:+) 'する必要があります。 – d11wtq

+0

@ d11wtq '&'は必要ありません。 'reduce'はシンボル' reduce(:+) 'を受け取ります。 –

5

なぜ注入使用せずに?注射はまさにあなたが望むものです。

products.inject(0) { |total, (k, v)| total + v.last } 

確かに、より手続き的な解決方法を使用できますが、なぜですか?

+0

私は実際に注射方法を理解していません。私は1ヵ月ほど前にルビーを学び始めました。私はそれについて読むことを試みたが、方法を理解していない。あなたが私のためにそれをクリアするなら、おそらくそれを使用するでしょう。本当に貴重なことがあると聞いています。 –

+1

ブロックの最初の引数 'total'は、ブロックの戻り値で常に更新されます。ここで、0はtotalの初期値であり、そこからは引き続き加算されます。それを追加するたびに、 'total'の新しい値がコレクションの次の値のブロックに返されます。最終的にすべての値を0に追加しました。IRBやPryで配列を使って試してみましょう。 '*'、 '-'、' + 'のような簡単な数学をやってみると意味があります。 – d11wtq

0

これが唯一の組み込み関数を使用してルビーの任意のバージョンで動作するはずです:

products.values.map(&:last).reduce(&:+) # => 212.95 
+0

'&'は必要ありません。単純な 'reduce(:+)'も使えます。 'reduce(0、:+)'は、空のハッシュに対しても機能するので、より良いです。 –