I'm trying to iterate over the elements of a collection (in the sense
of: accumulating stuff as I'm going along), and (possibly) stop before
the end is reached, based on some condition. (Something like: sum up
the elements of a collection until a limit has been reached.)
I was looking for something along the lines of Oleg Kiselyov's
enumeratee/iteratee interface:
http://okmij.org/ftp/Streams.html
... but couldn't find anything like it in the collections interfaces.
In fact, the only way I could find of doing it involved either an
explicit use of an iterator (not functional), or break (not functional
either). There's no inherent reason why this needs to be imperative,
which is why I'd like to do it functionally.
Am I missing something?
--
Cheers =8-} Mike
Friede, V�lkerverst�ndigung und �berhaupt blabla
scala> sumUntilCondition(List(1,2,3,4), d => d > 9, 0)
res0: Double = 10.0
This is just a fold, and no doubt Tony will appear in a minute and do
some Type-Fu magic that puts my example to shame, but I think this
should give you an idea.
> Friede, Völkerverständigung und überhaupt blabla
>
scala> def stopCond(x: Int) = x == 3
stopCond: (x: Int)Boolean
scala> def condFold(a: (Int, Boolean), e: Int): (Int, Boolean) = a match {
| case (x, false) => (x, false)
| case (x, true) => if (stopCond(x)) (x, false) else (x+e, true)
| }
r: (a: (Int, Boolean),e: Int)(Int, Boolean)
scala> (1 to 10).foldLeft ((0,true)) (condFold)
res7: (Int, Boolean) = (3,false)
?
2011/2/11 Michael Sperber <spe...@deinprogramm.de>:
> Friede, Völkerverständigung und überhaupt blabla
>
--
С уважением,
Алексей Злобин.
sometimes, the iterative way is simpler.
-------- Original-Nachricht --------
> Datum: Fri, 11 Feb 2011 17:43:16 +0100
> Von: Michael Sperber <spe...@deinprogramm.de>
> An: scala...@googlegroups.com
> Betreff: [scala-user] Iteration with stop condition - functionally
> Friede, Völkerverständigung und überhaupt blabla
-------- Original-Nachricht --------
> Datum: Fri, 11 Feb 2011 19:57:51 +0300
> Von: Alexey Zlobin <alexey...@gmail.com>
> An: Michael Sperber <spe...@deinprogramm.de>
> CC: scala...@googlegroups.com
> Betreff: Re: [scala-user] Iteration with stop condition - functionally
scala> List(1,2,3,4,5,6).view.scanLeft(0)(_+_).takeWhile(x => x < 10).last
res4: Int = 6
Note the use of view to prevent the entire list from being traversed
when doing the scan.
Nate
Funny, if I understood correctly your question, I asked something very similar yesterday:
http://comments.gmane.org/gmane.comp.lang.scala.user/35817 - Partial loop run
If I adapt one of the answers with my test code (clumsy, I know), I would show this example:
class Foo
{
var r = 0
val rand = new scala.util.Random(System.nanoTime)
def isItOk() =
{
r = rand.nextInt(10)
println("One more: " + r)
r
}
}
object TT
{
def main(args: Array[String])
{
val foos = for (i <- 0 until 50) yield new Foo
val res = foos.takeWhile(_.isItOk() != 1).foldLeft(0)(_ + _.r)
println(res)
}
}
HTH.
--
Philippe Lhoste
-- (near) Paris -- France
-- http://Phi.Lho.free.fr
-- -- -- -- -- -- -- -- -- -- -- -- -- --
takeWhileM + State.
case class State[S, A](f: S => (S, A))
def takeWhileM[M[_], A](p: A => M[Boolean], as: List[A]): M[List[A]]
Implement yourself for fun, or see scalaz.
- --
Tony Morris
http://tmorris.net/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAk1VnIUACgkQmnpgrYe6r62yugCfcy3kbiUux3rsaXdGEjvF8SK2
1CkAn32Vs89T+dXUfbZ5vnqqujaY/89H
=rM+y
-----END PGP SIGNATURE-----