21

如何each在 ruby​​ 中设置循环的起始偏移量?我希望循环从而a[3]不是a[0]. 我该如何设置?

a = [ab, cd, ef, gh, hi, jk]

a.each do |i|
#some stuff
end
4

5 回答 5

47

另一种可能更直接和可读的可能性是使用Array#drop

a.drop(3).each do |i|
  # do something with item i
end

现在,如果与继承自 的其他方法结合使用,这确实会大放异彩Enumerable,因此很可能有更好的替代命令式each循环的方法。假设您要过滤提取的切片并在之后对其进行转换:

a = [0,1,2,3,4,5,6,7]
a.drop(3).select(&:even?).map { |x| x * 2 }
# => [8, 12]

或者说您要打印所有值的列表:

a = ["1", "2", "3", "4", "5"]
puts a.drop(3).join("\n")

输出:

4
5

这些继承自函数式编程的特性是 Ruby 如此强大的原因:)

于 2012-05-01T10:20:07.377 回答
23

each在数组的子部分上使用。在下面的示例中,从第四个元素到末尾:

a[3..-1].each do |i|
  #some stuff
end
于 2012-05-01T10:11:54.027 回答
4

这将帮助你

a[3..-1].each do |i|
  #your logic
end
于 2012-05-01T10:15:09.030 回答
3

大多数 Rubyist 忘记了旧的 for 循环:

n = 3
for i in n...a.size
  puts a[i]
end
于 2012-05-01T10:17:53.280 回答
2

基准

对于那些对这些方法的基准比较感兴趣的人:)

require 'benchmark/ips'

a = Array.new(1000) { |i| i } 
drop_point = 500

Benchmark.ips do |x|
  x.report('drop(x)') do
    a.drop(drop_point).each { |el| el + 1 }
  end

  x.report('[x...-1]') do 
    a[drop_point..-1].each { |el| el + 1 }
  end

  x.report('for in') do
    n = drop_point
    size = a.size
    for i in n...size
      a[i] + 1
    end
  end

  x.report('while') do
    size = a.size
    i = drop_point
    while i < size
      a[i] + 1
      i += 1
    end
  end

  x.compare!
end

结果

Warming up --------------------------------------
             drop(x)     4.142k i/100ms
            [x...-1]     4.125k i/100ms
              for in     3.239k i/100ms
               while     5.391k i/100ms
Calculating -------------------------------------
             drop(x)     42.485k (± 2.3%) i/s -    215.384k in   5.072524s
            [x...-1]     42.533k (± 2.3%) i/s -    214.500k in   5.045832s
              for in     32.855k (± 2.5%) i/s -    165.189k in   5.030958s
               while     53.489k (± 4.5%) i/s -    269.550k in   5.049793s

Comparison:
               while:    53489.3 i/s
            [x...-1]:    42532.8 i/s - 1.26x  slower
             drop(x):    42484.7 i/s - 1.26x  slower
              for in:    32855.4 i/s - 1.63x  slower

结论

正如预期的那样,好的旧版本while是最快的,因为它没有block分配,但我更喜欢[x...-1]或者drop(x)因为它们更具可读性

于 2018-12-28T21:17:58.937 回答