Forum: Ruby loop questions

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
84dc575c33a123789521d53cad0f62ae?d=identicon&s=25 Lloyd Linklater (lloyd)
on 2007-05-10 14:33
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?
843881c344479c7e0de8f67b2c03a4e5?d=identicon&s=25 Niko (Guest)
on 2007-05-10 14:48
(Received via mailing list)
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
83ca41657a99b65d99889abe712ba5e2?d=identicon&s=25 Jason Roelofs (Guest)
on 2007-05-10 14:49
(Received via mailing list)
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
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2007-05-10 14:51
(Received via mailing list)
On 10.05.2007 14:33, Lloyd Linklater 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
2f4d4f9c35ea851bffb9a9cc2e086365?d=identicon&s=25 Harry Kakueki (Guest)
on 2007-05-10 14:58
(Received via mailing list)
On 5/10/07, Lloyd Linklater <lloyd@2live4.com> wrote:
> --
>
Is this what you want?

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

OR

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

Harry
84dc575c33a123789521d53cad0f62ae?d=identicon&s=25 Lloyd Linklater (lloyd)
on 2007-05-10 14:58
Excellent!  I *knew* that this language was top notch!

Thanks, gents!  :)
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (Guest)
on 2007-05-10 15:01
(Received via mailing list)
On Thu, May 10, 2007 at 09:33:08PM +0900, Lloyd Linklater 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.
84dc575c33a123789521d53cad0f62ae?d=identicon&s=25 Lloyd Linklater (lloyd)
on 2007-05-10 15:31
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!
1c0cd550766a3ee3e4a9c495926e4603?d=identicon&s=25 John Joyce (Guest)
on 2007-05-10 15:54
(Received via mailing list)
On May 10, 2007, at 10:31 PM, Lloyd Linklater 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.
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (Guest)
on 2007-05-10 17:36
(Received via mailing list)
On Thu, May 10, 2007 at 10:31:36PM +0900, Lloyd Linklater 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
This topic is locked and can not be replied to.