Ruby each_with_index offset
Can I define the offset of the index in the each_with_index loop iterator? My straight forward attempt failed:
some_array.each_with_index{|item, index = 1| some_func(item, index) }
Edit:
Clarification: I don't want an array offset I want that the index within the each_with_index doesn't start from 0 but e.g. 1.
Solution 1:
Actually, Enumerator#with_index
receives offset as an optional parameter:
[:foo, :bar, :baz].to_enum.with_index(1).each do |elem, i|
puts "#{i}: #{elem}"
end
outputs:
1: foo
2: bar
3: baz
BTW, I think it is there only in 1.9.2.
Solution 2:
The following is succinct, using Ruby's Enumerator class.
[:foo, :bar, :baz].each.with_index(1) do |elem, i|
puts "#{i}: #{elem}"
end
output
1: foo
2: bar
3: baz
Array#each returns an enumerator, and calling Enumerator#with_index returns another enumerator, to which a block is passed.
Solution 3:
1) The simplest is to substitute index+1
instead of index
to the function:
some_array.each_with_index{|item, index| some_func(item, index+1)}
but probably that is not what you want.
2) The next thing you can do is to define a different index j
within the block and use it instead of the original index:
some_array.each_with_index{|item, i| j = i + 1; some_func(item, j)}
3) If you want to use index in this way often, then define another method:
module Enumerable
def each_with_index_from_one *args, &pr
each_with_index(*args){|obj, i| pr.call(obj, i+1)}
end
end
%w(one two three).each_with_index_from_one{|w, i| puts "#{i}. #{w}"}
# =>
1. one
2. two
3. three
Update
This answer, which was answered a few years ago, is now obsolete. For modern Rubies, Zack Xu's answer will work better.
Solution 4:
If some_index
is somehow meaningful, then consider using a hash, rather than an array.
Solution 5:
I ran into it.
My solution not necessary is the best, but it just worked for me.
In the view iteration:
just add: index + 1
That's all for me, as I don't use any reference to those index numbers but just for show in a list.