Ruby each_with_index offset

前端 未结 10 1038
长发绾君心
长发绾君心 2020-12-12 23:32

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


        
相关标签:
10条回答
  • 2020-12-13 00:07

    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.

    0 讨论(0)
  • 2020-12-13 00:08

    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

    0 讨论(0)
  • 2020-12-13 00:10

    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) }
    
    0 讨论(0)
  • 2020-12-13 00:12

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

    0 讨论(0)
提交回复
热议问题