Automatic counter in Ruby for each?

RubySyntax

Ruby Problem Overview


I want to use a for-each and a counter:

i=0
for blah in blahs
    puts i.to_s + " " + blah
    i+=1
end

Is there a better way to do it?

Note: I don't know if blahs is an array or a hash, but having to do blahs[i] wouldn't make it much sexier. Also I'd like to know how to write i++ in Ruby.


Technically, Matt's and Squeegy's answer came in first, but I'm giving best answer to paradoja so spread around the points a bit on SO. Also his answer had the note about versions, which is still relevant (as long as my Ubuntu 8.04 is using Ruby 1.8.6).


Should've used puts "#{i} #{blah}" which is a lot more succinct.

Ruby Solutions


Solution 1 - Ruby

As people have said, you can use

each_with_index

but if you want indices with an iterator different to "each" (for example, if you want to map with an index or something like that) you can concatenate enumerators with the each_with_index method, or simply use with_index:

blahs.each_with_index.map { |blah, index| something(blah, index)}

blahs.map.with_index { |blah, index| something(blah, index) }

This is something you can do from ruby 1.8.7 and 1.9.

Solution 2 - Ruby

[:a, :b, :c].each_with_index do |item, i|
  puts "index: #{i}, item: #{item}"
end

You can't do this with for. I usually like the more declarative call to each personally anyway. Partly because its easy to transition to other forms when you hits the limit of the for syntax.

Solution 3 - Ruby

Yes, it's collection.each to do loops, and then each_with_index to get the index.

You probably ought to read a Ruby book because this is fundamental Ruby and if you don't know it, you're going to be in big trouble (try: http://poignantguide.net/ruby/).

Taken from the Ruby source code:

 hash = Hash.new
 %w(cat dog wombat).each_with_index {|item, index|
   hash[item] = index
 }
 hash   #=> {"cat"=>0, "wombat"=>2, "dog"=>1}

Solution 4 - Ruby

If you don't have the new version of each_with_index, you can use the [zip](http://ruby-doc.org/core/classes/Enumerable.html#M003138 "Enumerable#zip") method to pair indexes with elements:

blahs = %w{one two three four five}
puts (1..blahs.length).zip(blahs).map{|pair|'%s %s' % pair}

which produces:

1 one
2 two
3 three
4 four
5 five

Solution 5 - Ruby

As to your question about doing i++, well, you cannot do that in Ruby. The i += 1 statement you had is exactly how you're supposed to do it.

Solution 6 - Ruby

The [enumerating enumerable][1] series is pretty nice.

[1]: http://www.globalnerdy.com/tag/enumerable/ "enumerating enumerable"

Solution 7 - Ruby

If you want to get index of ruby for each, then you can use

.each_with_index

Here is an example to show how .each_with_index works:

range = ('a'..'z').to_a
length = range.length - 1
range.each_with_index do |letter, index|
	print letter + " "
	if index == length
		puts "You are at last item"
	end
end

This will print:

a b c d e f g h i j k l m n o p q r s t u v w x y z You are at last item

Solution 8 - Ruby

If blahs is a class that mixes in Enumerable, you should be able to do this:

blahs.each_with_index do |blah, i|
  puts("#{i} #{blah}")
end

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDan RosenstarkView Question on Stackoverflow
Solution 1 - RubyparadojaView Answer on Stackoverflow
Solution 2 - RubyAlex WayneView Answer on Stackoverflow
Solution 3 - RubyMatt RogishView Answer on Stackoverflow
Solution 4 - RubyGeorgeView Answer on Stackoverflow
Solution 5 - RubypopeView Answer on Stackoverflow
Solution 6 - RubyAndrew GrimmView Answer on Stackoverflow
Solution 7 - RubyIlyas karimView Answer on Stackoverflow
Solution 8 - RubyRoy PardeeView Answer on Stackoverflow