Ruby each_with_index偏移量

时间:2011-04-13 08:26:42

标签: ruby iteration

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

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

编辑:

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

10 个答案:

答案 0 :(得分:106)

实际上,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 :(得分:47)

以下是简洁的,使用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返回另一个枚举器,传递一个块。

答案 2 :(得分: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的答案会更好。

答案 3 :(得分:4)

如果some_index在某种程度上有意义,那么请考虑使用散列而不是数组。

答案 4 :(得分:4)

我遇到了它。

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

在视图迭代中:

只需添加:index + 1

这一切都适合我,因为我没有使用任何对这些索引号的引用,只是为了在列表中显示。

答案 5 :(得分: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大于你的数组大小,它将会出错。这是因为:

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

这有点儿hacky

UPD 2

至于你更新了你的问题,现在你不需要数组偏移,但索引偏移,所以@sawa解决方案将适合你

答案 6 :(得分:1)

Ariel是对的。这是处理这个问题的最好方法,而且不是那么糟糕

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

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

答案 7 :(得分: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) }

答案 8 :(得分:1)

这适用于每个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

答案 9 :(得分:0)

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