56 votes

Est-il un bref syntaxe pour l'exécution d'un bloc de n fois à la Scala?

Je me retrouve à écrire du code comme ça quand je veux le répéter, certains exécution de n fois:

for (i <- 1 to n) { doSomething() }

Je suis à la recherche d'une syntaxe plus courte comme ceci:

n.times(doSomething())

Fait quelque chose comme cela existe dans Scala déjà?

MODIFIER

J'ai pensé à utiliser la Gamme de la méthode foreach (), mais le bloc a besoin de prendre un paramètre qu'il n'utilise jamais.

(1 to n).foreach(ignored => doSomething())

53voto

missingfaktor Points 44003

Vous pouvez facilement définir une à l'aide de Pimp My Bibliothèque de modèle.

scala> implicit def intWithTimes(n: Int) = new {        
     |   def times(f: => Unit) = 1 to n foreach {_ => f}
     | }
intWithTimes: (n: Int)java.lang.Object{def times(f: => Unit): Unit}

scala> 5 times {
     |   println("Hello World")
     | }
Hello World
Hello World
Hello World
Hello World
Hello World

40voto

sblundy Points 27163

La Gamme classe a une méthode foreach sur ce que je pense, c'est juste ce dont vous avez besoin. Par exemple, ceci:

 0.to(5).foreach(println(_))

produit

0
1
2
3
4
5

21voto

Apocalisp Points 22526

Avec scalaz 5:

doSomething.replicateM[List](n)

Avec scalaz 6:

n times doSomething

Et qui fonctionne comme vous le souhaitez avec la plupart des types (plus précisément, pour chaque monoïde):

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

scala> 5 times "foo"
res0: java.lang.String = foofoofoofoofoo

scala> 5 times List(1,2)
res1: List[Int] = List(1, 2, 1, 2, 1, 2, 1, 2, 1, 2)

scala> 5 times 10
res2: Int = 50

scala> 5 times ((x: Int) => x + 1).endo
res3: scalaz.Endo[Int] = <function1>

scala> res3(10)
res4: Int = 15

scala> 5 times putStrLn("Hello, World!")
res5: scalaz.effects.IO[Unit] = scalaz.effects.IO$$anon$2@36659c23

scala> res5.unsafePerformIO
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!

On pourrait aussi dire doSomething replicateM_ 5 qui ne fonctionne que si votre doSomething est une valeur monadique. Il a un meilleur type de sécurité, puisque vous pouvez faire ceci:

scala> putStrLn("Foo") replicateM_ 5
res6: scalaz.effects.IO[Unit] = scalaz.effects.IO$$anon$2@8fe8ee7

mais pas ce:

scala> { System.exit(0) } replicateM_ 5
<console>:15: error: value replicateM_ is not a member of Unit

Permettez-moi de vous voir arriver en Ruby.

5voto

huynhjl Points 26045

Je ne suis pas au courant de quoi que ce soit dans la bibliothèque. Vous pouvez définir un utilitaire de conversion implicite et de classe que vous pouvez importer en tant que de besoin.

class TimesRepeat(n:Int) {
  def timesRepeat(block: => Unit): Unit = (1 to n) foreach { i => block }
}
object TimesRepeat {
  implicit def toTimesRepeat(n:Int) = new TimesRepeat(n)
}

import TimesRepeat._

3.timesRepeat(println("foo"))

Rahul vient de poster une semblable réponse pendant que j'écrivais ce...

2voto

Adrian Points 1255

Il peut être aussi simple que cela:

scala> def times(n:Int)( code: => Unit ) {
          for (i <- 1 to n) code
       }
times: (n: Int)(code: => Unit)Unit

scala> times(5) {println("here")}
here
here
here
here
here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X