如何在Scala中调用方法n次?

Jon*_*nas 18 recursion closures loops scala anonymous-function

我有一个案例,我想调用一个方法n次,其中n是一个Int.在Scala中以"功能"方式有一个很好的方法吗?

case class Event(name: String, quantity: Int, value: Option[BigDecimal])

// a list of events
val lst = List(
    Event("supply", 3, Some(new java.math.BigDecimal("39.00"))),
    Event("sale", 1, None),
    Event("supply", 1, Some(new java.math.BigDecimal("41.00")))
    )

// a mutable queue
val queue = new scala.collection.mutable.Queue[BigDecimal]

lst.map { event =>
    event.name match {
        case "supply" => // call queue.enqueue(event.value) event.quantity times
        case "sale" =>   // call queue.dequeue() event.quantity times
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为关闭是一个很好的解决方案,但我不能让它工作.我也尝试过for-loop,但它不是一个漂亮的功能解决方案.

ten*_*shi 35

我认为最简单的解决方案是使用范围:

(1 to n) foreach (x => /* do something */)
Run Code Online (Sandbox Code Playgroud)

但是你也可以创建这个小帮助函数:

implicit def intTimes(i: Int) = new {
    def times(fn: => Unit) = (1 to i) foreach (x => fn)
}

10 times println("hello")
Run Code Online (Sandbox Code Playgroud)

此代码将打印"hello"10次.隐式转换intTimes使方法times可用于所有整数.所以在你的情况下它应该是这样的:

event.quantity times queue.enqueue(event.value) 
event.quantity times queue.dequeue() 
Run Code Online (Sandbox Code Playgroud)

  • `for(i < - 1 to n){/*做某事*/}`比`foreach`略短:) (2认同)

oxb*_*kes 12

不是你的问题的答案,但如果你有一个内同态(即转换A => A),然后使用scalaz你可以使用自然的monoidEndo[A]

N times func apply target
Run Code Online (Sandbox Code Playgroud)

以便:

scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._

scala> Endo((_:Int) * 2).multiply(5)
res3: scalaz.Endo[Int] = Endo(<function1>)

scala> res1(3)
res4: Int = 96
Run Code Online (Sandbox Code Playgroud)


Tra*_*own 10

一个功能更强大的解决方案将是使用一个倍的不可变队列和Queuefilldrop的方法:

 val queue = lst.foldLeft(Queue.empty[Option[BigDecimal]]) { (q, e) =>
   e.name match {
     case "supply" => q ++ Queue.fill(e.quantity)(e.value)
     case "sale"   => q.drop(e.quantity)
   }
 }
Run Code Online (Sandbox Code Playgroud)

或者甚至更好,在子类中捕获您的"supply"/ "sale"区别Event并避免尴尬的Option[BigDecimal]业务:

sealed trait Event { def quantity: Int }
case class Supply(quantity: Int, value: BigDecimal) extends Event
case class Sale(quantity: Int) extends Event

val lst = List(
  Supply(3, BigDecimal("39.00")),
  Sale(1),
  Supply(1, BigDecimal("41.00"))
)

val queue = lst.foldLeft(Queue.empty[BigDecimal]) { (q, e) => e match {
  case Sale(quantity)          => q.drop(quantity)
  case Supply(quantity, value) => q ++ Queue.fill(quantity)(value)
}}
Run Code Online (Sandbox Code Playgroud)

这并没有直接回答你的问题(如何调用一个指定次数的函数),但它绝对是更惯用的.


Lui*_*hys 8

import List._

fill(10) { println("hello") }
Run Code Online (Sandbox Code Playgroud)

简单,内置,你得到一个单位列表作为纪念品!

但是如果你在功能上进行编程,你将永远不需要多次调用函数.

  • "但如果你在功能上进行编程,你将永远不需要多次调用函数." "嗯? (2认同)

Ale*_*nov 5

递归:

def repeat(n: Int)(f: => Unit) { 
  if (n > 0) {
    f
    repeat(n-1)(f)
  }
}

repeat(event.quantity) { queue.enqueue(event.value) }
Run Code Online (Sandbox Code Playgroud)