Groovy';窥视';先用迭代器?

Groovy';窥视';先用迭代器?,groovy,iterator,closures,peek,Groovy,Iterator,Closures,Peek,我在循环中有各种各样的场景,在循环遍历项目进行处理时,我会先“偷看”或“跳过” 一种情况是,我正在枚举一个文件的行,在一行的末尾有一个“continuation”字符,指示将下一行与当前行合并。如果我只是简单地循环,这并不太难,我可以直接读下一行,然后碰撞我的计数器/索引 使用迭代器执行此操作的模式并不明显。我实际上希望在不退出关闭的情况下使用下一行。但我甚至不确定这是否可行。对于这个使用闭包的迭代模式,有没有什么好的设计模式,这样我就不必求助于一个不那么groovy的循环了?它可能是一种迭代器

我在循环中有各种各样的场景,在循环遍历项目进行处理时,我会先“偷看”或“跳过”

一种情况是,我正在枚举一个文件的行,在一行的末尾有一个“continuation”字符,指示将下一行与当前行合并。如果我只是简单地循环,这并不太难,我可以直接读下一行,然后碰撞我的计数器/索引


使用迭代器执行此操作的模式并不明显。我实际上希望在不退出关闭的情况下使用下一行。但我甚至不确定这是否可行。对于这个使用闭包的迭代模式,有没有什么好的设计模式,这样我就不必求助于一个不那么groovy的循环了?它可能是一种迭代器形式,带有一些堆栈,用于推/弹出项目以进行处理吗?

我会制作一个迭代器,负责合并行。对于行延续示例,迭代器可以从其构造函数中的文件中读取行,然后从行中读取其
next
方法,在找到延续字符时进行读取,以便在管道中的下一步之前解析延续字符。因此,您需要的任何状态机都将包含在迭代器中。

我在不久前实现了类似的功能。我有一个很大的文件,每行都有管道分隔的数据,数据可以在下一行继续,但我只能知道是否“偷看”下一行。最后,我将ArrayList作为堆栈与peek方法结合使用:

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
有趣的问题

这里的关键问题是,您需要在迭代中携带一些状态

实现这一点的一种方法是使用外部变量(这里我使用字符串数组和
列表#每个
,而不是文件和
文件#每个行
,但它们应该是类似的):

另一种方法是使用一个专门设计的迭代器,通过交互传递状态,如:


我通常在迭代器周围使用装饰器,如下所示:
def lines = [
  "Single line.",
  "Long \\",
  "line \\",
  "continuation.",
  "Single line."
]

def processLine(line) { println "Processing \"$line\""}

def continuation = ''
lines.each { line ->
  line = continuation + line
  if (line.endsWith('\\')) {
    continuation = line.take(line.size() - 1)
  }
  else {
    processLine(line)
    continuation = ''
  }
}
lines = lines.inject([]) { list, line ->
  if (list && list[-1].endsWith('\\'))
    list[-1] = list[-1][0..-2] + line
  else 
    list << line
  list
}

lines.each { processLine(it) }