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