我能否定义在each_with_index循环迭代器中的索引偏移量? 我的直接尝试失败了:
some_array.each_with_index{|item, index = 1| some_func(item, index) }
编辑:
澄清:我不想要一个数组偏移量,我想让每个_with_index中的索引不从0开始,而是从1开始。
实际上,Enumerator#with_index
方法接受 offset 作为一个可选参数:
[: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版本中。
with_index
没有参数,索引从0
开始。 - mpapis[: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返回另一个枚举器,并向其传递一个块。
1)最简单的方法是将index
替换为index+1
,并将其应用于该函数:
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
这个回答是几年前回答的,现在已经过时了。对于现代的Ruby来说,Zack Xu的答案会更好。
+1
改为+2
或+10
,它同样有效。 - sawasome_index
有一定的含义,那么考虑使用哈希表而非数组。我遇到了这个问题。
我的解决方案可能不是最好的,但它对我起作用了。
在视图迭代中:
只需要添加:index + 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) }
更新
另外,我应该注意到,如果偏移量超过了你的数组大小,它将会抛出一个错误。因为:
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(不太正规的)
更新2
既然您更新了问题,现在您不需要数组偏移量,而是需要索引偏移量,因此@sawa的解决方案对您来说将很好地运行。
这在每个 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
ary.each_with_index do |a, i|
puts i + 1
#other code
end
这是完全可以接受的,比我见过的大多数解决方案都要好。我一直认为这就是 #inject 的用途...哎呀。
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) }
offset = 2
some_array[offset..-1].each_with_index{|item, index| some_func(item, index+offset) }