Циклические различия в Ruby с использованием Range vs. Times
Я пытаюсь решить проблему Project Euler с помощью Ruby, я использовал 4 разных метода цикла, метод for-loop, times, range и upto, однако метод times только дает ожидаемый ответ, а for-loop, диапазон и выше метод нет. Я предполагаю, что они несколько одинаковы, но я этого не узнал. Может кто-нибудь объяснить различия между этими методами?
Здесь структура цикла, в которой я использовал
# for-loop method
for n in 0..1
puts n
end
0
1
=> 0..1
# times method
2.times do |n|
puts n
end
0
1
=> 2
# range method
(0..1).each do |n|
puts n
end
0
1
=> 0..1
# upto method
0.upto(1) do |n|
puts n
end
0
1
=> 0
Ответы
Ответ 1
Эта информация может быть легко получена путем проверки документации.
Array#each
имеет подпись array.each {|item| block } → array
, поэтому мы можем видеть, что возвращаемое значение foo.each { ... }
равно foo
.
Аналогично, Int#upto
имеет подпись int.upto(limit) {|i| block } => int
, так что x.upto(y) { ... }
всегда будет возвращать x
.
Затем мы также видим, что 2.times { ... }
вернет 2 из-за Integer#times
подпись.
У меня возникли проблемы с поиском нужной документации, но for x in y...
переводится на y.each do |x| ...
, поэтому ваш цикл for-in возвращает то же, что и ваш цикл .each
.
В любом случае, в зависимости от возвращаемых значений этих циклов построения... странный подход. Я не думаю, что это происходит много (вообще?) В идиоматическом коде Ruby.
Ответ 2
Если я правильно вас понял, вы спрашиваете, почему n.times
- единственный метод, который выполняет итерацию до, но не включает n
. В этом случае:
Для диапазонов это просто: x..y
определяет диапазон от x до y включительно, а x...y
определяет диапазон от x до y exclusive. Поэтому, если вы хотите, чтобы такое же поведение, как времена, использовало 0...n
.
Для x.upto(y)
существует только одна версия, которая будет выполнять итерацию до и включая y
. Это просто, как upto определяется и документируется для работы.
Также совершенно понятно, почему n.times
не содержит n: если он итерировал от 0 до n (включительно), он дал бы n+1
раз. Но так как метод называется n.times
, он должен явно давать только n раз.