我有一个迭代模块,它可以应用任意函数(Build generic reusable iteration module from higher order function),并且希望将它封装到一个进度条中。
val things = Range(1,10)
def iterationModule[A](
iterationItems: Seq[A],
functionToApply: A => Any
): Unit = {
iterationItems.foreach(functionToApply)
}
def foo(s:Int) = println(s)
iterationModule[Int](things, foo)一个基本的progressbar看起来可能是:
import me.tongfei.progressbar.ProgressBar
val pb = new ProgressBar("Test", things.size)
things.foreach(t=> {
println(t)
pb.step
})但是,如何截获传递给迭代器模块的函数并将其包围为progressbar,即调用pb.step
一个恼人的可能性是将可变的pb对象传递到每个函数中(让它实现一个接口)。但是,是否也可以拦截和包围由这个步进逻辑传递的函数呢?但是,当使用Seq().par.foreach循环时,这可能会有问题。
我需要在Scala2.11中工作的代码。
编辑
一个更复杂的例子:
val things = Range(1,100).map(_.toString)
def iterationModule[A](
iterationItems: Seq[A],
functionToApply: A => Any,
parallel: Boolean = false
): Unit = {
val pb = new ProgressBar(functionToApply.toString(), iterationItems.size)
if (parallel) {
iterationItems.par.foreach(functionToApply)
} else {
iterationItems.foreach(functionToApply)
}
}
def doStuff(inputDay: String, inputConfigSomething: String): Unit = println(inputDay + "__"+ inputConfigSomething)
iterationModule[String](things, doStuff(_, "foo"))函数应该能够接受迭代项和附加参数。
编辑2
import me.tongfei.progressbar.ProgressBar
val things = Range(1,100).map(_.toString)
def doStuff(inputDay: String, inputConfigSomething: String): Unit = println(inputDay + "__"+ inputConfigSomething)
def iterationModulePb[A](items: Seq[A], f: A => Any, parallel: Boolean = false): Unit = {
val pb = new ProgressBar(f.toString, items.size)
val it = if (parallel) {
items.par.iterator
} else {
items.iterator
}
it.foreach { x =>
f(x)
pb.step()
}
}
iterationModulePb[String](things, doStuff(_, "foo"))经过一些讨论,我了解了如何在标准迭代器中使用Seq。
发布于 2019-12-07 17:01:35
对于Scala 2.13,这将是最普遍的形式。
import me.tongfei.progressbar.ProgressBar
def iterationModule[A](items: IterableOnce[A], f: A => Any): Unit = {
val (it, pb) =
if (items.knowSize != -1)
items.iterator -> new ProgressBar("Test", items.knowSize)
else {
val (iter1, iter2) = items.iterator.split
iter1 -> new ProgressBar("Test", iter2.size)
}
it.foreach { x =>
f(x)
pb.step()
}
}注意:大多数更改只是为了使代码更通用,但是一般的想法是创建一个函数,它包装了原始函数和对ProgressBar的调用。
编辑
一种简化的2.11解决方案
def iterationModule[A](items: Seq[A], parallel: Boolean = false)
(f: A => Any): Unit = {
val pb = new ProgressBar("test", items.size)
val it = if (parallel) {
items.iterator.par
} else {
items.iterator
}
it.foreach { a =>
f(a)
pb.step()
}
}https://stackoverflow.com/questions/59228233
复制相似问题