Search code examples
arraysrubyiteratorenumerator

Can I manipulate the current iteration of the collection being currently iterated over?


Say I have a collection of @lines, and I want to iterate over it, but I want to manipulate how it is iterated over based on the contents of the collection, how do I do that?

i.e. something like this:

@lines.each_with_index do |line, index|
   if (index % 3 = 0)
      jump_to index == next_multiple_of_3
   end
end

So what that may look like is something like this:

Element | Index
a       | 1
b       | 2
c       | 3
f       | 6
g       | 7
h       | 8
i       | 9
l       | 12

How can I do that?

Edit 1

Note that, as I explained in a comment below, I don't necessarily always want to jump to a specific multiple. Basically, I would want to jump to some arbitrary index that is determined by something that happens within the current iteration.

So the first go around, it could jump 3 indices up, but then the next time it jumps 7 indices up, then for the next 5 times it jumps by 1 like normal, then it jumps by 2 indices up.

The only constant is that the way to determine how it progresses through the original iteration is based on something that happens within the block of the current iteration.


Solution

  • Use a while loop and manage the index yourself. We were discouraging people from doing this for ages. But this is the one case where it's appropriate. :)

    idx = 0
    while idx < @lines.length
      line = @lines[idx]
      idx += condition ? x : y # or whatever logic you have
    end
    

    This, of course, assumes that @lines is capable of random access. If it's not, make it an array.