views:

317

answers:

7

Is there a Ruby version of for-loop similar to the one in Java/C(++)?

In Java:

for (int i=0; i<1000; i++) {
    // do stuff
}

The reason is because I need to do different operations based on the index of the iteration. Looks like Ruby only has a for-each loop?

Am I correct?

+8  A: 

Yes you can use each_with_index

collection = ["element1", "element2"]
collection.each_with_index {|item,index| puts item; puts index}

the 'index' variable gives you the element index during each iteration

nas
+1  A: 

You can user each with index.

Waseem
+4  A: 

In Ruby, the for loop may be implemented as:

1000.times do |i|
  # do stuff ...
end

If you want both the element and the index then the each_with_index syntax is probably best:

collection.each_with_index do |element, index|
  # do stuff ...
end

However the each_with_index loop is slower since it provides both the element and index objects for each iteration of the loop.

erik
`each_with_index` is not slower than doing an array lookup for each element. It should be quite a bit faster.
Chuck
Correct, but if you don't perform the array lookup for every iteration of the loop, `each_with_index` may be slower. It ultimately depends on the loop of course.
erik
Well, yes, if you're not using an array, obviously you won't want to use an array method...
Chuck
+10  A: 

Ruby tends to use iterators rather than loops; you can get all the function of loops with Ruby's powerful iterators.

There are several choices to do this, let's assume you have an array 'arr' of size 1000.

1000.times {|i| puts arr[i]}
0.upto(arr.size-1){|i| puts arr[i]}
arr.each_index {|i| puts arr[i]}
arr.each_with_index {|e,i| puts e} #i is the index of element e in arr

All these examples provide the same functionality

+2  A: 

How about step?

0.step(1000,2) { |i| puts i }

is equivalent to:

for (int i=0; i<=1000; i=i+2) {
    // do stuff
}

/I3az/

draegtun
A: 

times is recommended over each_with_index. times is around 6 times faster. Run the code below.

require "benchmark"

TESTS = 10_000_000
array = (1..TESTS).map { rand }
Benchmark.bmbm do |results|
  results.report("times") do
    TESTS.times do |i|
      # do nothing
    end
  end

  results.report("each_with_index") do
    array.each_with_index do |element, index|
      # Do nothing
    end
  end
end

I got the result as below with my MacBook (Intel Core2Duo).

Rehearsal ---------------------------------------------------
times             1.130000   0.000000   1.130000 (  1.141054)
each_with_index   7.550000   0.210000   7.760000 (  7.856737)
------------------------------------------ total: 8.890000sec

                      user     system      total        real
times             1.090000   0.000000   1.090000 (  1.099561)
each_with_index   7.600000   0.200000   7.800000 (  7.888901)
TK
you are not accessing the array elements in the 'times' benchmark - you are comparing an array lookup with an empty loop
A: 

when i just need the numbers (and not wanting to iterate) I prefer this:

(0..10000).each do |v|
    puts v
end
banister