2012-02-26 26 views
8

Tengo un hash como este.sumando números en un hash en ruby ​​

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

Tiene un número de elemento =>[product, price].

Me gustaría resumir todos los precios sin utilizar el método de inyección.

¿Alguien me puede ayudar, por favor?

+6

No entender 'inject' no es razón para no usarlo. En su lugar, debe leerlo, el estilo de programación funcional a menudo puede conducir a un código más conciso y legible. –

+0

De acuerdo con @NiklasB. aquí, 'inject' /' reduce' es un método fantástico que, una vez que lo entiendas, hará que gran parte de tu código sea mucho más simple y elegante. –

Respuesta

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

La matriz no tiene un método de suma en ruby ​​puro – Fivell

+0

Tienes que 'reducir (&: +)' para eso. – d11wtq

+0

@ d11wtq No necesita el '&' allí, 'reduce' acepta un símbolo:' reduce (: +) '. –

5

Por qué sin utilizar inyectar? Inyectar es exactamente lo que quieres.

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

Claro, puede utilizar una solución más de procedimiento, pero ¿por qué?

+0

realmente no entiendo el método de inyección. Empecé a aprender ruby ​​hace un mes. He intentado leer sobre eso, pero simplemente no entiendo el método. Si lo aclaras para mí, probablemente lo use. Escuché que puede ser realmente valioso. –

+1

El primer argumento del bloque, 'total', se actualiza constantemente con el valor de retorno del bloque. Aquí, 0 es el valor inicial de 'total', y a partir de ahí, seguimos agregando a él. Cada vez que lo agreguemos, el nuevo valor de 'total' se devuelve al bloque para el siguiente valor en la colección. Eventualmente, has agregado cada valor a 0. Experimenta con IRB o Pry, usando una matriz para empezar, simplemente haciendo cálculos simples, como '*', '-' y' + 'y tendrá sentido. – d11wtq

0

Esto debería funcionar en cualquier versión de Rubí usando sólo las funciones incorporadas:

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

El '&' no es necesario, un simple 'reduce (: +)' también funcionaría. 'reduce (0,: +)' es aún mejor porque también funciona para hashes vacíos. –