Reputation: 8064
is it possible to write the folowing code with the scala standard library ?
def foldWhile[A,B](s: Stream[A])(z: B)(w: B ⇒ Boolean)(op: (B, A) ⇒ B): B = {
if(s.isEmpty) z
else {
if(w(z)) foldWhile(s.tail)(op(z, s.head))(w)(op)
else z
}
}
foldWhile(Stream(1,2,3,4))(0)(_ <= 3)((acc, v) => acc + v)
Upvotes: 2
Views: 828
Reputation: 3033
Stream(1,2,3,4).scanLeft(0){_ + _}.takeWhile(_ <= 3).last
UPDATE 1
So, funny story, I'm friends with Guillaume (he asked the question before I got to the office) and above is actually what he wants, the bug is in the code in the question.
But if you want the exact logic of the question, you could write something like this:
val results = Stream(1,2,3,4).scanLeft(0){_ + _}
val index = results.indexWhere(_ > 3)
results(index)
I haven't found a one liner for it yet though.
UPDATE 2
Stream(1,2,3,4).scanLeft(0){_ + _}.dropWhile(_ <= 3).head
Upvotes: 2
Reputation: 11366
Though I personally think it is grimey, you can have a return in the middle of a fold:
def foldWhile[A,B](s: TraversableOnce[A])(z: B)(w: B ⇒ Boolean)(op: (B, A) ⇒ B): B =
s.foldLeft[B](z)((b,a) ⇒ if(w(b)) op(b,a) else return b)
Upvotes: 7