2012-03-15 2 views
6

Я изучаю Ruby, и в книге, из которой я учусь, было немного разговоров о методе upto. Я смущен. Что именно он делает?Метод «upto» в Ruby

Пример:

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

Возможно, вам захочется найти другую книгу. В этом случае это 'upto' <' grades.length.times' <'grades.each' <' grades.inject (0,: +) '. –

+0

Надеюсь, ваша книга не говорит, что 'upto' является оператором; это обычный метод. Соответственно отредактировал ваш вопрос. –

+1

@ Marc-AndréLafortune Много книг Ruby - вот что они говорят вам точно, что * Ruby имеет, но не * почему * вы использовали бы один путь над другим. :( –

ответ

20

Давайте попробуем объяснить:

Вы Определяете массив

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

и подготовить переменный для хранения суммы:

sum = 0 

grades.length является 6 (есть 6 элементов в массив), (grades.length - 1) is 5.

с 0.upto(5) Вы петля от 0 до 5, loop_index будет 0, затем 1 ...

Первый элемент массива - grades[0] (индекс в массиве начинается с 0). Вот почему вы должны вычесть 1 из числа элементов.

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

Добавьте значение loop_index в сумму.

sum += grades[loop_index] 
end 

Теперь вы зацикливаете на каждом элементе и суммируете все элементы массива.

Вы можете вычислить среднее:

average = sum/grades.length 

Теперь вы пишете результат на стандартный вывод:

puts average 

Это был не-рубинового как синтаксис. Ruby, как вы могли бы сделать это следующим образом:

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

Добавление на основе Marc-Андреса комментарий:

Вы можете также использовать inject, чтобы избежать, чтобы определить первоначальную сумму:

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

или еще короче:

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

Хорошее объяснение. Я бы просто добавил, что 'foo = start, enum.each {| i | foo = some_function (foo, i)}' - шаблон, для которого Rubyist может использовать 'inject'. –

+0

Спасибо за подсказку с инъекцией. Этот метод всегда завязывает сучки в моем мозгу ;) – knut

1

Upto выполняет блок заданный один раз для каждого числа от исходного числа "Шифрование до" переданного аргумента. Например:

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

напечатает числа от 1 до 10.

1

Это просто в Руби another way to do a loop/iterator. Он говорит, что делает это действие n раз на основании того, что i является первым номером числа в parens как предел.

0

Альтернатива, которая выглядит как Руби меня

require 'descriptive_statistics' 

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

Конечно, это зависит от того, что вы делаете.

0

Мой пример был бы это:

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

Так что вы на самом деле делаете здесь говорит, я хочу, чтобы подсчитать от 1 до числа 5, это конкретно то, что эта часть говорит:

1.upto(5) 

последняя часть кода (а блок) просто выводя итерацию происходит через графа от 1 до 5. это вывод, который вы могли бы ожидать, чтобы увидеть:

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

Примечание: Это можно записать еще один способ, если вы используете мультилинии:

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

Надеется, что это помогает.

Смежные вопросы