Skip iteration in each loop

I want to skip iteration for few values depending on dynamic condition.

Say I have a persons array [1,2,3,4,5,6,7,8] and while iterating if the
one of the values equals 2, then it should skip iteration for the next
two values (in this case it is 3 and 4)

In this case the output should be: [1,2,5,6,7,8]

persons = [1,2,3,4,5,6,7,8]

persons.each do |x|
if x == 2
# the next x value should be 5 in my case
end
p x
end

How can I do it in Ruby ?

···

--
Posted via http://www.ruby-forum.com/.

Saurav Chakraborty wrote in post #1097028:

I want to skip iteration for few values depending on dynamic condition.

Say I have a persons array [1,2,3,4,5,6,7,8] and while iterating if the
one of the values equals 2, then it should skip iteration for the next
two values (in this case it is 3 and 4)

In this case the output should be: [1,2,5,6,7,8]

persons = [1,2,3,4,5,6,7,8]

persons.each do |x|
if x == 2
# the next x value should be 5 in my case
end
p x
end

How can I do it in Ruby ?

Okay! So do you want the original array intact or output to hold in a
different array?

clarify please?

···

--
Posted via http://www.ruby-forum.com/\.

I doubt this is the best method, but here's one way to do it

irb(main):001:0> persons = [1,2,3,4,5,6,7,8]
=> [1, 2, 3, 4, 5, 6, 7, 8]
irb(main):002:0> skip_next = 0
=> 0
irb(main):003:0> persons.each do |x|
irb(main):004:1* if x == 2
irb(main):005:2> skip_next = 2
irb(main):006:2> elsif skip_next > 0
irb(main):007:2> skip_next -= 1
irb(main):008:2> next
irb(main):009:2> end
irb(main):010:1> p x
irb(main):011:1> end
1
2
5
6
7
8

···

--
Posted via http://www.ruby-forum.com/.

You could use Array.partition for that if you wanted both outputs as
well

discard, keep = [1, 2, 3, 4, 5, 6, 7, 8].partition { |n| [3,4].index n }

···

--
Posted via http://www.ruby-forum.com/.

try manual iteration, ri next

eg,

$ cat test.rb
people = (1..30).each
skippers = [2,10]
loop do
  person=people.next rescue exit

  if skippers.include? person
    person.times{person = people.next}
    next
  end

  p person
end

botp@u:~
$ ruby test.rb
1
5
6
7
8
9
21
22
23
24
25
26
27
28
29
30

kind regards -botp

···

On Fri, Feb 15, 2013 at 4:11 PM, Saurav Chakraborty <lists@ruby-forum.com>wrote:

I want to skip iteration for few values depending on dynamic condition.

Say I have a persons array [1,2,3,4,5,6,7,8] and while iterating if the
one of the values equals 2, then it should skip iteration for the next
two values (in this case it is 3 and 4)

In this case the output should be: [1,2,5,6,7,8]

Can you explain the dynamic condition? Your example has been solved by a number of people for an equality test, but do you require something more complicated? #reject will probably get you most of the way there, but there may be other ways of approaching the problem if 'dynamic' is something involving expensive operations, possible exceptions (integer overflow–if 2**x> 100–could be a problem), etc.

-a.

···

On 15 Feb 2013, at 3:11 AM, Saurav Chakraborty <lists@ruby-forum.com> wrote:

I want to skip iteration for few values depending on dynamic condition.

Say I have a persons array [1,2,3,4,5,6,7,8] and while iterating if the
one of the values equals 2, then it should skip iteration for the next
two values (in this case it is 3 and 4)

In this case the output should be: [1,2,5,6,7,8]

persons = [1,2,3,4,5,6,7,8]

persons.each do |x|
if x == 2
# the next x value should be 5 in my case
end
p x
end

How can I do it in Ruby ?

--
Posted via http://www.ruby-forum.com/\.

Thanks everyone. Robert's solution has helped me in solving my problem.

···

--
Posted via http://www.ruby-forum.com/.

Love U Ruby wrote in post #1097030:

Okay! So do you want the original array intact or output to hold in a
different array?

clarify please?

The output should be in a different array.

···

--
Posted via http://www.ruby-forum.com/\.

Joel Pearson wrote in post #1097034:

I doubt this is the best method, but here's one way to do it

irb(main):001:0> persons = [1,2,3,4,5,6,7,8]
=> [1, 2, 3, 4, 5, 6, 7, 8]
irb(main):002:0> skip_next = 0
=> 0
irb(main):003:0> persons.each do |x|
irb(main):004:1* if x == 2
irb(main):005:2> skip_next = 2
irb(main):006:2> elsif skip_next > 0
irb(main):007:2> skip_next -= 1
irb(main):008:2> next
irb(main):009:2> end
irb(main):010:1> p x
irb(main):011:1> end
1
2
5
6
7
8

And, rearranging that slightly:

    .tap do |a|
      skip_next = 0
      persons.each do |p|
        if skip_next > 0
          skip_next -= 1
          next
        end
        a << p
        skip_next = 2 if p == 2
      end
    end

···

--
Posted via http://www.ruby-forum.com/\.

Another approach:

irb(main):001:0> persons = [1,2,3,4,5,6,7,8]
=> [1, 2, 3, 4, 5, 6, 7, 8]

irb(main):011:0> show = -1
=> -1
irb(main):012:0> persons.each_with_index {|x, i| show = i + 2 if x ==
2; puts x if i > show}
1
5
6
7
8
=> [1, 2, 3, 4, 5, 6, 7, 8]

or

irb(main):013:0> persons.inject(0) {|miss, x| if x == 2 then 2 else
puts x if miss <= 0; miss - 1 end}
1
5
6
7
8
=> -4

Kind regards

robert

···

On Fri, Feb 15, 2013 at 1:17 PM, botp <botpena@gmail.com> wrote:

On Fri, Feb 15, 2013 at 4:11 PM, Saurav Chakraborty <lists@ruby-forum.com> > wrote:

I want to skip iteration for few values depending on dynamic condition.

Say I have a persons array [1,2,3,4,5,6,7,8] and while iterating if the
one of the values equals 2, then it should skip iteration for the next
two values (in this case it is 3 and 4)

In this case the output should be: [1,2,5,6,7,8]

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

A good rule of thumb when dealing with a "primitive" like an Array: if
you're using a counter variable, you can probably get there faster:

[1, 2, 3, 4, 5, 6].reject { |n| n >= 3 || n <= 5 }

This returns a new Array. You can also use #select for selecting, and both
methods have a version ending in ! to modify the object in place.

Check out the documentation for Array and the Enumerable module which it
includes. Familiarity with those methods will help jog your memory.