2012-02-26 9 views
8

Ho un hash come questo.sommare i numeri in un hash in rubino

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

Ha un numero articolo =>[product, price].

Vorrei riassumere tutti i prezzi senza utilizzare il metodo di iniezione.

Qualcuno può aiutarmi per favore?

+6

Non capire 'inject' è alcuna ragione per non usarlo. Invece, dovresti semplicemente leggerlo, lo stile di programmazione funzionale può spesso portare a un codice più conciso e leggibile. –

+0

Concordato con @NiklasB. qui, 'inject' /' reduce' è un metodo fantastico che, una volta compreso, renderà molto più semplice e più elegante gran parte del codice. –

risposta

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

L'array non ha metodo sum in puro rubino – Fivell

+0

Devi 'ridurre (&: +)' per quello. – d11wtq

+0

@ d11wtq Non è necessario il '&' lì, 'reduce' accetta un simbolo:' riduci (: +) '. –

5

Perché senza l'utilizzo di iniettare? Inietti è esattamente quello che vuoi.

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

Certo, è possibile utilizzare una soluzione più procedurale, ma perché?

+0

non capisco il metodo di iniezione. Ho appena iniziato a studiare Ruby circa un mese fa. Ho provato a leggerlo, ma non capisco il metodo. Probabilmente lo userò se lo elimini per me. Ho sentito che può essere davvero prezioso. –

+1

Il primo argomento del blocco, 'total', viene costantemente aggiornato con il valore restituito del blocco. Qui, 0 è il valore iniziale di 'total', e da lì continuiamo ad aggiungerlo. Ogni volta che aggiungiamo ad esso, il nuovo valore di 'total' viene passato di nuovo nel blocco per il valore successivo nella raccolta. Alla fine hai aggiunto ogni valore a 0. Sperimenta con esso in IRB o in Pry, usando una matrice per iniziare, semplicemente facendo semplici matematica, come '*', '-' e' + 'e avrà un senso. – d11wtq

0

Questo dovrebbe funzionare in qualsiasi versione di Ruby utilizzando solo le funzioni built-in:

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

Il '&' non è necessario, anche un semplice 'reduce (: +)' funzionerebbe. 'reduce (0,: +)' è ancora più bello perché funziona anche per gli hash vuoti. –