【问题标题】:Ruby each_with_index offsetRuby each_with_index 偏移量
【发布时间】:2011-08-04 12:29:57
【问题描述】:

我可以在 each_with_index 循环迭代器中定义索引的偏移量吗? 我的直接尝试失败了:

some_array.each_with_index{|item, index = 1| some_func(item, index) }

编辑:

澄清:我不想要数组偏移量,我希望 each_with_index 中的索引不是从 0 开始,而是从 0 开始。 1.

【问题讨论】:

  • 你使用什么 Ruby 版本?
  • 抱歉没写,我用的是Ruby 1.9.2

标签: ruby iteration


【解决方案1】:

是的,你可以

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

另外我应该注意到,如果偏移量大于你的数组大小,它会出错。因为:

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

我们可以在这里做什么:

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

或预先验证偏移量:

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

这有点骇人听闻

UPD 2

就您更新问题而言,现在您不需要数组偏移量,而是索引偏移量,因此@sawa 解决方案将适合您

【讨论】:

    【解决方案2】:
    offset = 2
    some_array[offset..-1].each_with_index{|item, index| some_func(item, index+offset) }
    

    【讨论】:

      【解决方案3】:

      1) 最简单的方法是将index+1 代替index 替换为函数:

      some_array.each_with_index{|item, index| some_func(item, index+1)}
      

      但这可能不是你想要的。

      2) 接下来你可以在块内定义一个不同的索引j 并使用它来代替原来的索引:

      some_array.each_with_index{|item, i| j = i + 1; some_func(item, j)}
      

      3)如果你想经常这样使用索引,那么定义另一个方法:

      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
      


      更新

      几年前回答的这个答案现在已经过时了。对于现代红宝石,Zack Xu 的答案会更好。

      【讨论】:

      • 不好的是,即使数组中没有更多元素,它也会迭代
      • @fl00r 真的吗?在我的示例中,它在三点后停止。
      • 但是如果偏移量是 2 还是 10?在您的情况下,偏移量为零。我的意思是您的 (3) 中没有任何偏移
      • @fl00r 您只需将我的代码中的+1 更改为+2+10。它也有效。
      • 天啊,作者编辑了他的帖子,所以他需要索引偏移而不是数组。
      【解决方案4】:

      实际上,Enumerator#with_index 接收偏移量作为可选参数:

      [:foo, :bar, :baz].to_enum.with_index(1).each do |elem, i|
        puts "#{i}: #{elem}"
      end
      

      输出:

      1: foo
      2: bar
      3: baz
      

      顺便说一句,我认为它只存在于 1.9.2 中。

      【讨论】:

      • 在 1.8.7 中只有 with_index 没有参数,索引来自 0
      • 实际上,一个更短的答案是可能的,请看下面我的。
      【解决方案5】:

      如果some_index 有某种意义,请考虑使用散列,而不是数组。

      【讨论】:

        【解决方案6】:

        我遇到了。

        我不需要的解决方案是最好的,但它对我有用。

        在视图迭代中:

        只需添加:index + 1

        这就是我的全部内容,因为我没有使用任何对这些索引号的引用,而只是为了在列表中显示。

        【讨论】:

          【解决方案7】:

          爱丽儿是对的。这是处理这个问题的最好方法,而且还不错

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

          这是完全可以接受的,并且比我见过的大多数解决方案都要好。我一直认为这就是#inject 的用途……哦,好吧。

          【讨论】:

            【解决方案8】:

            另一种方法是使用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) }
            

            【讨论】:

              【解决方案9】:

              这适用于每个 ruby​​ 版本:

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

              对于泛型数组:

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

              【讨论】:

              • 第二个例子中缺少一个括号。
              【解决方案10】:

              以下内容简洁,使用 Ruby 的 Enumerator 类。

              [:foo, :bar, :baz].each.with_index(1) do |elem, i|
                  puts "#{i}: #{elem}"
              end
              

              输出

              1: foo
              2: bar
              3: baz
              

              Array#each 返回一个枚举器,调用 Enumerator#with_index 返回另一个枚举器,向其传递一个块。

              【讨论】:

                猜你喜欢
                • 2012-06-04
                • 2016-02-23
                • 2015-05-08
                • 1970-01-01
                • 2016-01-31
                • 2012-08-25
                • 2012-04-13
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多