2012-02-26 33 views
8

Tôi có một băm như thế này.số tổng hợp trong một băm trong ruby ​​

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

Nó có số mặt hàng =>[product, price].

Tôi muốn tổng hợp tất cả giá mà không cần sử dụng phương thức tiêm.

Bất kỳ ai có thể giúp tôi không?

+6

Không hiểu 'inject' là không có lý do để không sử dụng nó. Thay vào đó, bạn chỉ cần đọc lên trên nó, phong cách lập trình chức năng thường có thể dẫn đến ngắn gọn hơn, mã có thể đọc được. –

+0

Đồng ý với @NiklasB. Ở đây, 'inject' /' reduce' là một phương pháp tuyệt vời, một khi bạn hiểu nó, sẽ làm cho phần lớn mã của bạn trở nên đơn giản và thanh lịch hơn. –

Trả lời

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

Mảng không có phương pháp tổng hợp trong ruby ​​tinh khiết – Fivell

+0

Bạn phải 'giảm ​​(&: +)' cho điều đó. – d11wtq

+0

@ d11wtq Bạn không cần '&' ở đó, 'reduce' chấp nhận một biểu tượng:' reduce (: +) '. –

5

Tại sao không sử dụng tiêm? Tiêm là chính xác những gì bạn muốn.

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

Chắc chắn, bạn có thể sử dụng giải pháp thủ tục hơn, nhưng tại sao?

+0

tôi không thực sự hiểu phương pháp tiêm. Tôi mới bắt đầu học ruby ​​khoảng một tháng trước. Tôi đã thử đọc về nó, nhưng chỉ không hiểu phương pháp. Nếu bạn xóa nó cho tôi, tôi có lẽ sẽ sử dụng nó. Tôi nghe nói rằng nó có thể thực sự có giá trị. –

+1

Đối số đầu tiên cho khối, 'tổng số', được cập nhật liên tục với giá trị trả về của khối. Ở đây, 0 là giá trị ban đầu của 'total', và từ đó, chúng ta tiếp tục bổ sung vào nó. Mỗi khi chúng ta thêm vào nó, giá trị mới của 'tổng' được chuyển trở lại vào khối cho giá trị tiếp theo trong bộ sưu tập. Cuối cùng bạn đã thêm mọi giá trị vào 0. Thử nghiệm với nó trong IRB hoặc Pry, sử dụng một Array để bắt đầu, chỉ cần thực hiện các phép toán đơn giản, như '*', '-' và' + 'và nó sẽ có ý nghĩa. – d11wtq

0

này nên làm việc trong bất kỳ phiên bản của Ruby chỉ sử dụng các chức năng built-in:

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

Không cần '&', một 'giảm ​​(: +)' đơn giản cũng sẽ hoạt động. 'reduce (0,: +)' thậm chí còn đẹp hơn vì nó cũng hoạt động đối với các băm rỗng. –

Các vấn đề liên quan