Ruby each_with_index offset

RubyIteration

Ruby Problem Overview


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.

Ruby Solutions


Solution 1 - Ruby

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 - Ruby

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 - Ruby

  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.

  1. 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)}

  2. 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 - Ruby

If some_index is somehow meaningful, then consider using a hash, rather than an array.

Solution 5 - Ruby

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.

Solution 6 - Ruby

Yes, you can

some_array[offset..-1].each_with_index{|item, index| some_func(item, index) }
some_array[offset..-1].each_with_index{|item, index| some_func(item, index+offset) }
some_array[offset..-1].each_with_index{|item, index| index+=offset; some_func(item, index) }

UPD

Also I should notice that if offset is more than your Array size it will though an error. Because:

some_array[1000,-1] => nil
nil.each_with_index => Error 'undefined method `each_with_index' for nil:NilClass'

What can we do here:

 (some_array[offset..-1]||[]).each_with_index{|item, index| some_func(item, index) }

Or to prevalidate offset:

 offset = 1000
 some_array[offset..-1].each_with_index{|item, index| some_func(item, index) } if offset <= some_array.size

This is little hacky

UPD 2

As far as you updated your question and now you need not Array offset, but index offset so @sawa solution will works fine for you

Solution 7 - Ruby

Ariel is right. This is the best way to handle this, and it's not that bad

ary.each_with_index do |a, i|
  puts i + 1
  #other code
end

That is perfectly acceptable, and better than most of the solutions I've seen for this. I always thought this was what #inject was for...oh well.

Solution 8 - Ruby

Another approach is to use map

some_array = [:foo, :bar, :baz]
some_array_plus_offset_index = some_array.each_with_index.map {|item, i| [item, i + 1]}
some_array_plus_offset_index.each{|item, offset_index| some_func(item, offset_index) }

Solution 9 - Ruby

This works in every ruby version:

%W(one two three).zip(1..3).each do |value, index|
  puts value, index
end

And for a generic array:

a.zip(1..a.length.each do |value, index|
  puts value, index
end

Solution 10 - Ruby

offset = 2
some_array[offset..-1].each_with_index{|item, index| some_func(item, index+offset) }

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
QuestionMarkView Question on Stackoverflow
Solution 1 - RubyMladen JablanovićView Answer on Stackoverflow
Solution 2 - RubyZack XuView Answer on Stackoverflow
Solution 3 - RubysawaView Answer on Stackoverflow
Solution 4 - RubyAndrew GrimmView Answer on Stackoverflow
Solution 5 - RubyAriel De La RosaView Answer on Stackoverflow
Solution 6 - Rubyfl00rView Answer on Stackoverflow
Solution 7 - Rubyboulder_rubyView Answer on Stackoverflow
Solution 8 - RubyAndrew GrimmView Answer on Stackoverflow
Solution 9 - RubyfotanusView Answer on Stackoverflow
Solution 10 - RubyipsumView Answer on Stackoverflow