对于具有条件增量的循环

时间:2016-02-17 17:07:53

标签: ruby loops

我希望for循环根据条件递增。循环通常应将其索引i增加1,但如果满足某些条件(i == 20),则应将i的值设置为50 }(跳过21 - 49)。伪代码就是这样的:

for(i = 0; i < 100;)
  if i == 20
    i = 50
  else
    i = i++
  end 
end

我该如何实现?

5 个答案:

答案 0 :(得分:5)

这可能是少数while循环适合的情况之一:

i = 0
while i < 10
  if i == 2
    i = 5
  else
    i += 1
  end

  p i
end
# 1
# 2
# 5
# 6
# 7
# 8
# 9
# 10

或者,您可以在语言中添加自己的C风格for循环,实际上非常简单:

class Proc
  def for(iter=->{}, &blk)
    return unless call
    yield
    iter.()
    self.for(iter, &blk)
  end
end

i = 0
-> { i < 10 }.for -> { if i == 2 then i = 5 else i += 1 end } { p i }
# 1
# 2
# 5
# 6
# 7
# 8
# 9
# 10

这相当于以下C风格的for循环(在ECMAScript中演示):

for(let i = 1; i <= 10; i === 2 ? i = 5 : i++) {
  console.log(i);
}
// 1
// 2
// 5
// 6
// 7
// 8
// 9
// 10

答案 1 :(得分:2)

由于您需要根据递增的i变量重新评估条件,您可以使用while语句:

i = 0

while i < 100  do
  if i == 20
     i = 50
  else
     i = i+1
  end 
end

答案 2 :(得分:1)

不确定那里的数字是多么的字面意思,但这里只是一个更优雅的技巧:

[0...20, 50..100].flat_map(&:to_a).each do |i|
  # ...
end

[*0...20, *50..100].each do |i|
  # ...
end

答案 3 :(得分:0)

我不推荐这个,但是当使用带有块的枚举器时,它是跳过索引的一种方法。假设

skip_index  = 2
skip_number = 4
arr = [*0..10]

然后:

arr = arr[skip_number..10] if skip_index.zero?
arr.each do |i|
  puts "i=#{i}"
  # do something
  arr.replace([*skip_number..10]) if i == skip_index-1
end
i=0
i=1
i=6
i=7
i=8
i=9
i=10

这可以提供一些有关each如何运作的见解。

答案 4 :(得分:0)

这是简洁的while循环,可以实现你想要做的事情。

i = 0
while i < 100
    i == 20 ? i = 50 : i += 1
    p i
end

这将返回: 1 2 3 4 五 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 50 51 52 53 ... 100