首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将高阶函数封装到进度条中

将高阶函数封装到进度条中
EN

Stack Overflow用户
提问于 2019-12-07 16:50:35
回答 1查看 114关注 0票数 1

我有一个迭代模块,它可以应用任意函数(Build generic reusable iteration module from higher order function),并且希望将它封装到一个进度条中。

代码语言:javascript
复制
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看起来可能是:

代码语言:javascript
复制
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中工作的代码。

编辑

一个更复杂的例子:

代码语言:javascript
复制
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

代码语言:javascript
复制
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。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-07 17:01:35

对于Scala 2.13,这将是最普遍的形式。

代码语言:javascript
复制
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解决方案

代码语言:javascript
复制
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()
  }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59228233

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档