将高阶函数包装到进度栏中

我有一个迭代模块,该模块可以应用任意函数(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循环时,这可能会出现问题。

我需要代码才能在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,"foo"))

经过一番讨论,我弄清楚了如何在标准迭代器中使用Seq。

liweisb 回答:将高阶函数包装到进度栏中

对于 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://www.f2er.com/2956878.html

大家都在问