Normal For Loop

I’m new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

I know I can do that with a while loop, but I enjoy the compactness of
the above statement. There are many times where Ruby’s for-each loops
just don’t do the trick.

Also, is there anything like i++ or do I always have to do i=i+1 ?

Cory C. wrote:

I’m new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

I know I can do that with a while loop, but I enjoy the compactness of
the above statement. There are many times where Ruby’s for-each loops
just don’t do the trick.

We would be very interested to see a loop in C that cannot be rewritten
in Ruby. Care to give us an example?

Also, is there anything like i++ or do I always have to do i=i+1 ?

You can use i += 1.

On Mon, Mar 3, 2008 at 3:10 PM, Cory C. [email protected] wrote:

I’m new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

I know I can do that with a while loop, but I enjoy the compactness of
the above statement. There are many times where Ruby’s for-each loops
just don’t do the trick.

There is 5.times {|i| } if the count is known at cycle start.
Then you have array.each {}, and the whole bunch from Enumerable
(each_with_index, select, find, map, inject, …)

On Mon, 3 Mar 2008 23:10:09 +0900, Cory C. [email protected] wrote:

I’m new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

I know I can do that with a while loop, but I enjoy the compactness of
the above statement. There are many times where Ruby’s for-each loops
just don’t do the trick.

[“foo”, “bar”, “baz”].each_with_index {|elem, i|
puts “#{elem} #{i}”
}

Kristian

Jano S. wrote:

On Mon, Mar 3, 2008 at 3:10 PM, Cory C. [email protected] wrote:

I’m new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

I know I can do that with a while loop, but I enjoy the compactness of
the above statement. There are many times where Ruby’s for-each loops
just don’t do the trick.

There is 5.times {|i| } if the count is known at cycle start.
Then you have array.each {}, and the whole bunch from Enumerable
(each_with_index, select, find, map, inject, …)

Not to mention Numeric#step:

1.step(10, 2) { |i| print i, " " }

And Integer#upto:

5.upto(10) { |i| print i, " " }

On Mar 3, 9:10 am, Cory C. [email protected] wrote:

I’m new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

for n in 1…10
puts n
end

It seems more common in ruby to do things like

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

or

(1…10).each {|n| puts n}

If you mean that you want your condition and your increment to depend
on things that you won’t know about until after the loop has been
running for a while, then yeah, you might have to use a while loop.
This doesn’t seem to come up much, though. Perhaps you could post a
specific example.

I know I can do that with a while loop, but I enjoy the compactness of
the above statement. There are many times where Ruby’s for-each loops
just don’t do the trick.

With a little creativity, not so many, in my experience.

Also, is there anything like i++ or do I always have to do i=i+1 ?

i=i+1 is the way to do it. There is some rationale for this, but I
don’t remember what it is.

JM

On Mon, Mar 3, 2008 at 3:29 PM, [email protected]
[email protected] wrote:

i=i+1 is the way to do it. There is some rationale for this, but I
don’t remember what it is.

IIRC, the rationale is that variables in ruby are just references to
objects, so you cannot call methods
on variables themselves. You call methods on objects they reference.
That means a call (except assignment)
cannot change the object a variable points to.

i.e. i = 3 that means, variable i points to/references object 3 of class
Fixnum.
if there was a call ++, (i++) that would mean the same as 3++. 3++
call can be written so that it returns 4
(actually it’s called 3.succ), but there’s no way to assign 4 back to
i. It would still point to 3. And because Fixnums are
singletons (there’s only one “3” object) they are read only, so
there’s no 3.succ!

I understand that all of these for-each style loops are available, but I
don’t want to always go through the entire loop, sometimes I want to
stop at some earlier condition.

I tried to do this the other night, but right now I can’t find a good
example so here it goes:

a = some_array
minValue = 999999
for(i=0; i<a.length && minValue!=0; i+=1) {
minValue = (5000 - a[i]).abs
}

This isn’t the best example. However, there are many times like the
loop above where I want to go through the whole thing, but if I find
exactly what I am looking for, I want to bail out early instead of
wasting that processing time.

Also, I sometimes may want to not actually iterate straight through, but
browse through the array in some more complex order.

On Mar 3, 9:37 am, Cory C. [email protected] wrote:

I tried to do this the other night, but right now I can’t find a good
example so here it goes:

a = some_array
minValue = 999999
for(i=0; i<a.length && minValue!=0; i+=1) {
minValue = (5000 - a[i]).abs

}

What does this example do exactly? It seems to run until it finds a
value in a that is equal to 5000, and then stop without reporting
anything.

a.detect {|n| 5000 == n}

or

a.any? {|n| 5000 == n}

See, this is actually more concise and readable, I think.

This isn’t the best example. However, there are many times like the
loop above where I want to go through the whole thing, but if I find
exactly what I am looking for, I want to bail out early instead of
wasting that processing time.

Also, I sometimes may want to not actually iterate straight through, but
browse through the array in some more complex order.

The point is not that no examples exist, but that they realistically
don’t come up very much. Get familiar with the methods in Enumerable,
Array, and Numeric. Each time you want to write a for loop, try and
use one of those instead, and if you get stuck, ask for advice.
You’re solution will almost always be more readable, and maybe 1 time
in 100 you’ll need to use a while loop.

JM

Alle Monday 03 March 2008, [email protected] ha scritto:

See, this is actually more concise and readable, I think.
don’t come up very much. Get familiar with the methods in Enumerable,
Array, and Numeric. Each time you want to write a for loop, try and
use one of those instead, and if you get stuck, ask for advice.
You’re solution will almost always be more readable, and maybe 1 time
in 100 you’ll need to use a while loop.

JM

If you want to exit the loop before all iterations are done, you can use
break.

Stefano

Cory C. ha scritto:

minValue = (5000 - a[i]).abs
}

This isn’t the best example. However, there are many times like the
loop above where I want to go through the whole thing, but if I find
exactly what I am looking for, I want to bail out early instead of
wasting that processing time.

In this case you can use “break” construct (which I, personally,
love). For example,

minValue = 999999
a.each do |x|
minValue = (5000-x).abs
break if minValue==0
end

(I did not actually try it, but it should work)

Also, I sometimes may want to not actually iterate straight through, but
browse through the array in some more complex order.

In this case I’m afraid that you must resort to a while… (BTW, I
always considered
C-style “for” as a “while” in disguise… :wink:

Cory C. wrote:
[for-loops instead of Array#each and friends]

a = some_array
minValue = 999999
for(i=0; i<a.length && minValue!=0; i+=1) {
minValue = (5000 - a[i]).abs
}

Break is your friend;
Some solutions for this example:

No. 1

(assuming that you are going to process the element, in this case,

printing it to STDOUT and adding a newline):

a = [100, 200, 3000, 5000, 80000] # Arbitrary Array initialisation,
# will be needed for all examples.
a.each {|i|
break if (5000-i).abs == 0
puts i
}
100
200
3000
==>nil

No. 2

returning an array with elements not meeting the condition

a.reject { |i| (5000-i).abs == 0 } # Can also be used as ‘select’
# with inverted condition
==>[100, 200, 3000, 80000]

No. 3

returning an array without elements > 5000

a.select { |i| i < 5000 }
==>[100, 200, 3000]

No. 4

contrived example, using #map and #compact

Warning: Don’t try this at home

a.map { |i| i < 5000 ? i : nil }.compact
==>[100, 200, 3000]

No. 5

contrived example again, this time using ‘size’ and artificial

‘index’; using exact condition, so ‘unless’ is needed instead of

‘if’. Using puts for ‘debug’ messages, or instead of processing

values. Less readable.

a.size.times { |i|
break unless (5000 - a[i]).abs != 0
puts a[i]
}
100
200
3000
==>nil

This isn’t the best example. However, there are many times like the
loop above where I want to go through the whole thing, but if I find
exactly what I am looking for, I want to bail out early instead of
wasting that processing time.

That’s what ‘break’ is for.

Also, I sometimes may want to not actually iterate straight through, but
browse through the array in some more complex order.

For Array manipulation, selection etc, refer to ‘ri Array’ - I can’t
see how ‘C-style for loops’ would help there either.

t.

Alright, you people have convinced me. Break seems like a good
solution, I like that you can put a condition after it. The last
submission seems very interested and I’m excited to learn all of these
different array functions.

Anyone know anything about “Rails for PHP Developers” book? I have been
programming in PHP sense I was like 13, it is burned into my head. I
like scripting in Ruby, but I’m still very uncomfortable with Rails
development. Is that book any good?

On Mon, Mar 3, 2008 at 6:10 AM, Cory C. [email protected] wrote:

I’m new to Ruby. Is there such thing as a C++ style (and most others)
for loop in Ruby? What I mean by that is:

for( init, while-condition, increment ) { function-here }

Simply put, no, Ruby has nothing that works quite like the C-style for
loop.

I know I can do that with a while loop, but I enjoy the compactness of
the above statement.

Usually, there is a simpler compact idiom using the iterator methods in
the
Enumerable module or specific container classes like Array if you need
something more compact than a while loop.

There are many times where Ruby’s for-each loops
just don’t do the trick.

The main looping tehcnique in Ruby is using iterator methods. You
could make something like the C-style for loop using them, with the
caveat
that all the loop parameters have to be specified as proc objects. It
would
be something like (this is code from the top of my head):

module Kernel
def cfor (init, condition, increment)
init.call
while condition.call
yield
increment.call
end
end
end

But, even if proc objects didn’t make calling this a little ugly,
you really don’t need it: there is generally a better more specific
way of doing things in Ruby.

For instance, in the example you give later in the thread:

a = some_array
minValue = 999999
for(i=0; i<a.length && minValue!=0; i+=1) {
minValue = (5000 - a[i]).abs
}

You seem to want to find the index of the first item in the array
that equals 5000 (which is what the value of i is when you bail
out) or the absolute value of 5000 minus the last item value in
the area (what minValue is if you fail to bail out).

so:

a = some_array
i = a.index(5000) || a.length
minValue = (i<a.length) ? 0 : (5000-a.last).abs

You can probably do something more elegant depending on
what you are doing with the results.

Also, is there anything like i++ or do I always have to do i=i+1 ?

You can do i+=1, i=i.succ, or i=i.next, if you prefer, but Ruby doesn’t
have
the increment or decrement operators of the C family.

I tried to do this the other night, but right now I can’t find a good
example so here it goes:

a = some_array
minValue = 999999
for(i=0; i<a.length && minValue!=0; i+=1) {
minValue = (5000 - a[i]).abs
}

This isn’t the best example. However, there are many times like the
loop above where I want to go through the whole thing, but if I find
exactly what I am looking for, I want to bail out early instead of
wasting that processing time.

Also, I sometimes may want to not actually iterate straight through, but
browse through the array in some more complex order.

I have a “good” example. In my case I want to iterate a collection,
skipping a variable number of elements based on a given element.
In this case, the C for construct (counter_init, cycle_condition,) would
be useful because I wouldn’t have to initialize the counter variable
outside of the scope, and I can increment the counter inside the loop.

The code is something like this:

for ( i = 0; i < elements.size; ) do
if elements[ i ].is_a?( OneType )
do_operation( elements[ i ] );
i += 1;
elsif elements[ i ].is_a?( AnotherType )
sub_elements = []
begin
sub_elements << elements[ i
i += 1;
end while elements[ i ].is_a?( AnotherType )
do_another_operation( sub_elements )
else

end
end

This example doesn’t pretend to be clever/correct/well constructed, but
is a real-world case where this kind of loop would be useful.

On Sat, Jan 15, 2011 at 3:52 AM, Saverio M.
[email protected]wrote:

This isn’t the best example. However, there are many times like the
be useful because I wouldn’t have to initialize the counter variable
begin
is a real-world case where this kind of loop would be useful.


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

It is probably unwise to put different types of data all in the same
array,
but here is my attempt (relies on 1.9 Enumerable method #chunk
module Enumerable - RDoc Documentation)

these just record what params they received

def do_operation(element)
@do_operation ||= Array.new
@do_operation << element
end

def do_another_operation(elements)
@do_another_operation ||= Array.new
@do_another_operation << elements
end

sequences of Symbols should be considered a single element

and Fixnums should be considered a single element

(the data should probably not be stored like this)

elements = [1,2,:a,:b,3,4,5,9,2,:a,:b]

chunk the data by its class

chunks = elements.chunk(&:class)
chunks.to_a # => [[Fixnum, [1, 2]], [Symbol, [:a, :b]], [Fixnum, [3, 4,
5,
9, 2]], [Symbol, [:a, :b]]]

look at each chunk, if they are fixnums, treat them individually

if they are symbols, treat them as a collection

chunks.each do |klass,chunk|
if Fixnum == klass
chunk.each { |e| do_operation e }
elsif Symbol == klass
do_another_operation chunk
else
# …
end
end

What did the methods receive?

@do_operation # => [1, 2, 3, 4, 5, 9, 2]
@do_another_operation # => [[:a, :b], [:a, :b]]

This piece of code was done as an exercise from Learn Ruby The Hard
Way.
I think this is more along the line of the type of for loop you are
looking for. The function’s purpose may seem trivial but let me know if
this helped anyone.

def number_increaser2(max_number, increment)

i = 0

numbers = []

for i in (0…max_number).step(increment)
if max_number > 0
numbers.push(i)
puts i
puts “Numbers now: #{numbers.join(” “)}”
else
puts “Max_number was too little!!\n”
return []
end
end

return numbers
end

On Oct 23, 2013, at 1:20 PM, Roy G. [email protected] wrote:

Is there a limited number (if so, is there a simple way find out how
many and what they are?), or can new methods be written indefinitely?


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

You should check out the Enumerable module:

[email protected] wrote in post #640913:

… Get familiar with the methods in Enumerable,
Array, and Numeric. Each time you want to write a for loop, try and
use one of those instead, and if you get stuck, ask for advice.

I am very new to Ruby, as you will see…

So far I’ve counted while, until, for, each, step (2 varieties), upto,
downto, each_with_index, times…

Is there a limited number (if so, is there a simple way find out how
many and what they are?), or can new methods be written indefinitely?

Yes, and you can write some very creative loops if you want, as abstract
or as precise as you like. There are some great options with
multiple-variable loops. Using blocks and yield makes for some amazing
loop options in Ruby.