红宝石的each_with_index偏移量


84

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

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

编辑:

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


您使用什么Ruby版本?
fl00r 2011年

对不起,我不写,但我使用Ruby 1.9.2
马克

Answers:



50

以下是使用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返回另一个枚举数,将一个块传递给该枚举数。


5

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 2011年

@ fl00r真的吗?在我的示例中,它在三点后停止。
sawa

但是,如果偏移是2或10?在您的情况下,偏移量为零。我的意思是您(3)的位置没有任何偏移
fl00r 2011年

@ fl00r您只需将+1我的代码中的更改为+2+10。它的作品也是如此。
sawa

OMG,作者编辑了他的文章,所以他需要索引偏移量而不是数组。
fl00r 2011年


4

我碰到了。

我的解决方案不一定是最好的,但是它对我来说才有效。

在视图迭代中:

只需添加:索引+1

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


3

是的你可以

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

我还要注意,如果offset大于您的Array大小,则会出现错误。因为:

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解决方案对您来说很好


1

Ariel是对的。这是处理此问题的最佳方法,而且还不错

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

这是完全可以接受的,并且比我所见过的大多数解决方案都要好。我一直以为#inject是为了...哦。


1

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

1

这适用于每个红宝石版本:

%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

在第二个示例中缺少括号。
晶圆薄2015年

0
offset = 2
some_array[offset..-1].each_with_index{|item, index| some_func(item, index+offset) }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.