【问题标题】:Groovy 'Peeking' ahead with an iterator?Groovy 'Peeking' 使用迭代器?
【发布时间】:2013-04-15 15:25:13
【问题描述】:

我在循环中有各种场景,我会在迭代处理项目时“偷看”或“跳过”。

一种情况是我正在枚举文件的行,并且行尾有一个“继续”字符,表示将下一行与当前行结合起来。如果我只是简单地循环并不太难,我可以阅读下一行,然后碰撞我的计数器/索引。

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

【问题讨论】:

标签: groovy iterator closures peek


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    前段时间我不得不实现类似的东西。我有一个大文件,每行都有管道分隔的数据,数据可以在下一行继续,但我只能知道我是否“偷看”了下一行。我结束了使用 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
    

    【讨论】:

      【解决方案3】:

      有趣的问题。

      这里的关键问题是你需要通过迭代携带一些状态。

      一种方法是使用外部变量(这里我使用的是字符串数组和List#each,而不是文件和File#eachLine,但它们应该是类似的):

      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 = ''
        }
      }
      

      另一种方法是使用专门设计用于通过交互传递状态的迭代器,例如Collection#inject

      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) }
      

      在这种情况下,我们首先连接连续的行,然后处理它们。

      在这两种情况下,输出都是:

      Processing "Single line."
      Processing "Long line continuation."
      Processing "Single line."
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-03
        • 2012-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多