将高阶函数包装到进度条中
Wrap higher order function into progress bar
我有一个可以应用任意函数的迭代模块 (),并且很想将它包装到进度条中。
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
循环时,这可能会出现问题。
我需要代码在 Scala 2.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 与标准迭代器一起使用。
对于 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()
}
}
注意:大部分更改只是为了使代码更通用,但总体思路只是创建一个函数,将原始函数和对 [=23= 的调用都包装起来]进度条.
编辑
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()
}
}
我有一个可以应用任意函数的迭代模块 (
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
循环时,这可能会出现问题。
我需要代码在 Scala 2.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 与标准迭代器一起使用。
对于 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()
}
}
注意:大部分更改只是为了使代码更通用,但总体思路只是创建一个函数,将原始函数和对 [=23= 的调用都包装起来]进度条.
编辑
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()
}
}