1

I want to skip a loop x times according to a condition that is determined at runtime. How can I do this?

for i in (0..5)
  if i==0
    3.times {next} # i=i+3 also doesnt work
  end
  puts i
end

Expect to output

3
4
5

EDIT: To clarify, the question is both the condition (ie i==0) and skipping x times iteration are determined dynamically at runtime, more convoluted example:

condition = Array.new(rand(1..100)).map{|el| rand(1..10000)} #edge cases will bug out
condition.uniq!

for i in (0..10000)
  if condition.include? i
    rand(1..10).times {next} # will not work
  end
  puts i
end
4
  • 1
    Not sure what is the exact input and output of your function. In your example, why not just use (3..5).each {|i| puts i} Commented Dec 20, 2015 at 3:43
  • @LeiChen, that's clearly how it should be done, so why not post an answer? Maybe def skip_first(range, nbr_to_skip). Commented Dec 20, 2015 at 4:08
  • please see my more convoluted example Commented Dec 20, 2015 at 4:41
  • 1
    For your "convoluted" example, I would prefer to compute an array keepers in advance, so you could just write for i in keepers..... That might be written condition = Array.new(rand(1..4)).flat_map do |el| first = rand(1..20); [*first..first+rand(0..4)]; end.uniq # => [7, 8, 9, 18, 6]; keepers = [*1..20]-condition #=> [1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 16, 17, 19, 20]. I realize there will be other situations where you will need next if .... within the block. Commented Dec 20, 2015 at 6:57

1 Answer 1

4

simple method to skip by a defined multiple.

array_list = (0..5).to_a
# Use a separate enum object to hold index position
enum = array_list.each 
multiple = 3

array_list.each do |value|
  if value.zero?     
    multiple.times { enum.next }
  end   
  begin puts enum.next rescue StopIteration end
end
Sign up to request clarification or add additional context in comments.

1 Comment

You can write that more succinctly: multiple = 3; enum = (0..5).each; loop do; multiple.times { enum.next } if enum.next.zero?; puts 'hi'; end. "hi" is printed thrice. This works because Enumerator#next raises a StopIteration exception when an attempt is made to go beyond the end of the enumeration, and Kernel#loop handles the exception by breaking out of the loop. You could instead write enum = (0..5).to_enum, which is arguably more descriptive.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.