Loop questions


#1

I am new to ruby and loving it so far and have beginner’s questions
about loops.

I wanted something like this:

for (int i = 1; i <= 5; i++)
printf("%d\n", [i]);

expecting:

1
2
3
4
5

I wrote this:

i = 5

i.times do
puts i.to_s
end

And got:

5
5
5
5
5

I am guessing that there is an internal variable that is incremented.
doh! Is there a way to get the changing variable in there without
having a separate variable in there?

Anyway, I then tried this:

for i in 1…5
puts i.to_s
end

Which worked as expected. But I had better use for a descending loop.
In pascal it would be

for i := 5 downto 1 do
writeln(’%d’, [i]);

but I could not figure out how to do that in a for loop. I looked
through several books and could not find the answer. Any tips?


#2

Hi

5.times do |i|
puts i
end

0
1
2
3
4

1.upto(5) do |i|
puts i
end

1
2
3
4
5

5.downto(1) do |i|
puts i
end

5
4
3
2
1


#3

i.times do |x|
puts x
end

You have to specify what the internal variable is.

As for the pascal code:

5.downto(1) do |x|
puts x
end

Here are a few links to help out with these types of questions:

Ruby Core API: http://ruby-doc.org/core/
Ruby Stdlib API: http://ruby-doc.org/stdlib

Pragmatic Programmers Guide: http://www.rubycentral.com/book/

_why’s poignant guide to Ruby (this one is odd):
http://poignantguide.net/ruby/

Jason


#4

On 5/10/07, Lloyd L. removed_email_address@domain.invalid wrote:

Is this what you want?

5.downto(1) do |x|
p x
end

OR

5.downto(1) {|x| p x}

Harry


#5

Excellent! I knew that this language was top notch!

Thanks, gents! :slight_smile:


#6

On 10.05.2007 14:33, Lloyd L. wrote:

1
i.times do

I am guessing that there is an internal variable that is incremented.
doh! Is there a way to get the changing variable in there without
having a separate variable in there?

The current value us passed to the block. So rather do

5.times do |i|
puts i
end

Anyway, I then tried this:

for i in 1…5
puts i.to_s
end

You don’t need the to_s here as puts will do that automatically.

Which worked as expected. But I had better use for a descending loop.
In pascal it would be

for i := 5 downto 1 do
writeln(’%d’, [i]);

but I could not figure out how to do that in a for loop. I looked
through several books and could not find the answer. Any tips?

5.downto 1 do |i|
puts i
end

or

5.step 1, -1 do |i|
puts i
end

If you think you need a /for/ loop:

for i in (1…5).to_a.reverse
puts i
end

But I’d rather not do this.

Kind regards

robert


#7

Excellent! I tried this right away and was able to make this mission
critical app:

b = " bottles of beer"
w = " on the wall. "
t = " Take one down and pass it around. "

99.downto(1) do |i|
puts i.to_s + b + w + i.to_s + b + “.” + t + (i - 1).to_s + b + w
end

Thanks again!


#8

On May 10, 2007, at 10:31 PM, Lloyd L. wrote:

Thanks again!


Posted via http://www.ruby-forum.com/.

the | | is like a |shoot| or |dumb-waiter| every time through the
iteration or loop it recieves something sometimes you can pass it
more than one thing. At first it’s a little weird but it really is
one of the most beautiful parts of ruby.


#9

On Thu, May 10, 2007 at 10:31:36PM +0900, Lloyd L. wrote:

Excellent! I tried this right away and was able to make this mission
critical app:

b = " bottles of beer"
w = " on the wall. "
t = " Take one down and pass it around. "

99.downto(1) do |i|
puts i.to_s + b + w + i.to_s + b + “.” + t + (i - 1).to_s + b + w
end

Whilst the following violates the Don’t Repeat Yourself mantra, I think
it’s
even clearer like this:

99.downto(1) do |i|
puts <<EOS
#{i} bottles of beer on the wall.
#{i} bottles of beer.
Take one down and pass it around.
#{i-1} bottles of beer on the wall.
EOS
end

Actually, there’s a bug which needs fixing:

def bottles(n)
“#{n} bottle#{n != 1 ? “s” : “”} of beer”
end
99.downto(1) { |i| puts <<EOS }
#{bottles(i)} on the wall.
#{bottles(i)}.
Take one down and pass it around.
#{bottles(i-1)} on the wall.
EOS


#10

On Thu, May 10, 2007 at 09:33:08PM +0900, Lloyd L. wrote:

Which worked as expected. But I had better use for a descending loop.
In pascal it would be

for i := 5 downto 1 do
writeln(’%d’, [i]);

but I could not figure out how to do that in a for loop. I looked
through several books and could not find the answer. Any tips?

http://www.rubycentral.com/book/tut_stdtypes.html

"Integers also support several useful iterators. We’ve seen one
already—7.times in the code example on page 47. Others include upto
and
downto, for iterating up and down between two integers, and step, which
is
more like a traditional for loop.

3.times { print "X " }
1.upto(5) { |i| print i, " " }
99.downto(95) { |i| print i, " " }
50.step(80, 5) { |i| print i, " " }

produces:

X X X 1 2 3 4 5 99 98 97 96 95 50 55 60 65 70 75 80"

(Or better, buy the second edition in paper or PDF form)

Regards,

Brian.