2012-03-15 33 views
6

Tôi đang học Ruby, và đã có một chút nói về phương pháp upto trong cuốn sách mà tôi đang học. Tôi bối rối. Chính xác thì nó làm gì?Phương pháp 'tối đa' trong Ruby

Ví dụ:

grades = [88,99,73,56,87,64] 
sum = 0 
0.upto(grades.length - 1) do |loop_index| 
    sum += grades[loop_index] 
end 
average = sum/grades.length 
puts average 
+5

Bạn có thể muốn tìm một cuốn sách khác. Trong trường hợp này, 'upto' <' grade.length.times' <'grade.each' <' grades.inject (0,: +) '. –

+0

Hy vọng rằng cuốn sách của bạn không nói 'upto' là một toán tử; đó là một phương pháp thông thường. Đã chỉnh sửa câu hỏi của bạn cho phù hợp. –

+1

@ Marc-AndréLafortune Rất nhiều sách Ruby giống như vậy - chúng cho bạn biết chính xác * những gì * Ruby có, nhưng không * tại sao * bạn sẽ sử dụng cách này sang cách khác. :( –

Trả lời

20

Chúng ta hãy thử một lời giải thích:

Bạn định nghĩa một mảng

grades = [88,99,73,56,87,64] 

và chuẩn bị một biến để lưu trữ các tổng:

sum = 0 

grades.length là 6 (có 6 yếu tố trong mảng), (grades.length - 1) là 5.

with 0.upto(5) bạn lặp lại từ 0 đến 5, loop_index sẽ là 0, sau đó 1 ...

Phần tử đầu tiên của mảng là grades[0] (chỉ mục trong mảng bắt đầu bằng 0). Đó là lý do tại sao bạn phải trừ 1 từ số phần tử.

0.upto(grades.length - 1) do |loop_index| 

Thêm giá trị loop_index để tính tổng.

sum += grades[loop_index] 
end 

Bây giờ bạn lặp lại từng phần tử và có tổng tất cả các phần tử của mảng.

Bạn có thể tính trung bình:

average = sum/grades.length 

Bây giờ bạn viết kết quả vào stdout:

puts average 

Đây là một tổ chức phi-ruby-như cú pháp . Ruby giống như bạn sẽ làm điều đó như thế này:

grades = [88,99,73,56,87,64] 
sum = 0 
grades.each do |value| 
    sum += value 
end 
average = sum/grades.length 
puts average 

Phụ lục dựa trên Marc-Andrés bình luận:

Bạn có thể sử dụng cũng inject để tránh để xác định số tiền ban đầu:

grades = [88,99,73,56,87,64] 
sum = grades.inject do |sum, value|  
    sum + value 
end 
average = sum/grades.length 
puts average 

Hoặc thậm chí ngắn hơn:

grades = [88,99,73,56,87,64] 
average = grades.inject(:+)/grades.length 
puts average 
+0

Giải thích tốt. 'foo = start, enum.each {| i | foo = some_function (foo, i)}' là một kiểu mà Rubyist có thể sử dụng 'inject'. –

+0

Cảm ơn gợi ý bằng cách tiêm. Phương pháp này làm cho luôn luôn nút thắt trong não của tôi ;) – knut

1

Upto thực hiện khối trao một lần cho mỗi số từ số gốc "tối đa" đối số truyền. Ví dụ:

1.upto(10) {|x| puts x} 

sẽ in ra các số từ 1 đến 10.

0

Một giải pháp thay thế trông giống Ruby với tôi là

require 'descriptive_statistics' 

grades=[88,99,73,56,87,64] 
sum = grades.sum 
average = grades.mean 
sd = grades.standard_deviation 

Tất nhiên nó phụ thuộc vào những gì bạn đang làm.

0

dụ của tôi sẽ có được điều này:

1.upto(5) { |i| puts "Countup: #{i}" } 

Vì vậy, những gì bạn đang thực sự làm gì ở đây đang nói, tôi muốn đếm lên từ 1 đến số 5, đó là cụ thể những gì phần này đang nói:

1.upto(5) 

các phần sau của mã (một khối) được chỉ xuất ra lặp đi qua các số từ 1 đến 5. Đây là sản phẩm bạn có thể mong đợi để xem:

Countup: 1 
    Countup: 2 
    Countup: 3 
    Countup: 4 
    Countup: 5 

Note: Đây có thể được viết là một cách khác nếu bạn đang sử dụng multilines:

1.upto(5) do |i| 
puts "Countup: #{i}" 
end 

Hope this helps.

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