Scala:从stdin读取时扫描左后一项
如果我使用scanLeft处理stdin的输入,结果输出总是在我上一次输入后面一行:
io.Source.stdin .getLines .scanLeft("START:")((accu,line) => accu + " " + line) .foreach(println(_)) 结果(我的手动输入前面是>): > first START: > second START: first > third START: first second 我想要的合理输出是: > first START: first > second START: first second > third START: first second third 如您所见,第一个输入行后面的输出应该已经包含第一个输入行的字符串. 我已经尝试使用.scanLeft(…).drop(1).foreach(…),但这会导致以下结果: > first > second START: first > third START: first second 如何正确省略纯种子以获得所需结果? [UPDATE] 但是,当然,如果scanLeft的任何替代品都没有将种子作为第一项发送到下一个迭代链中,我将更喜欢该解决方案. [UPDATE] 用户jwvh理解我的目标并提供了一个很好的解决方案.为了完善他们的建议,我寻求一种预处理线路的方法,然后再将它们发送到累积回调中.因此,readLine命令不应该在累积回调中调用,而是在我可以预先设置的不同链链接中调用. 解决方法
您可以使用Stream.iterate()代替scanDft()和StdIn.readLine来代替stdin.getLines.
def input = Stream.iterate("START:"){prev => val next = s"$prev ${io.StdIn.readLine}" println(next) next } 由于流被懒惰地评估,你需要一些方法来实现它. val inStr = input.takeWhile(! _.contains("quit")).last START: one //after input "one"<return> START: one two //after input "two"<return> START: one two brit //after input "brit"<return> START: one two brit quit //after input "quit"<return> //inStr: String = START: one two brit 如果这是一个要求,你实际上不必放弃getLines迭代器. def inItr = io.Source.stdin.getLines def input = Stream.iterate("START:"){prev => val next = s"$prev ${inItr.next}" println(next) next } 不确定这是否能解决您的意见.很大程度上取决于可能出现的错误以及确定方式. Stream.iterate(document()){ doc => val line = io.StdIn.readLine //blocks here .trim .filterNot(_.isControl) //other String or Char manipulations doc.update(line) /* at this point you have both input line and updated document to play with */ ... //handle error and logging requirements doc //for the next iteration } 我假设.update()修改源文档并且不返回任何内容(返回Unit).这是update()方法的常用签名. 其中大部分可以在调用链(_.method1.method2等)中完成,但有时候这会使事情变得更复杂. 不返回感兴趣值的方法仍然可以通过使用名为kestrel pattern的东西添加到调用链中. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |