Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy 'Peeking' ahead with an iterator?

I have various scenarios in loops where I would 'peek' or 'skip' ahead while iterating through items for processing.

One scenario is I'm enumerating through lines of a file, and there is a 'continuation' character at the end of a line indicating to combine the next line with the current line. If I'm simply looping that isn't too hard, I can just read the next line, and bump my counter/index.

It isn't as obvious is the pattern for doing this with my iterator. I effectively want to consume the next line(s) without exiting my closure. But I'm not even sure if that is possible. Are there any good design pattern for this iteration pattern using a closure, so I don't have to resort to a less groovy loop? Is it perhaps a form of iterator with some stack for pushing/popping items for processing?

like image 961
MarkE Avatar asked Apr 15 '13 15:04

MarkE


2 Answers

I'd make an iterator that would be in charge of combining lines. For the line continuation example, the iterator can take the lines read in from the file in its constructor, then have its next method read from the lines, reading ahead when it finds a continuation character, so that the continuation characters are resolved before the next step in the pipeline. So whatever state machine you need would be contained within the iterator.

like image 125
Nathan Hughes Avatar answered Nov 07 '22 12:11

Nathan Hughes


I had to implement something similar sometime ago. I had a large file with pipe-separated data on each line and the data could continue in the next line, but i could only know if i "peeked" the next line. I ended using ArrayList as a stack combined with a peek method:

def list = [1, 2, 3, 4, 5, 6, 7]

list.metaClass.peek = { delegate[-1] }

assert list.pop() == 7
assert list.pop() == 6
assert list.peek() == 5
assert list.peek() == 5
assert list.pop() == 5
assert list.pop() == 4
assert list.peek() == 3
like image 1
Will Avatar answered Nov 07 '22 11:11

Will